Skip to content

Conversation

@everettbu
Copy link
Contributor

@everettbu everettbu commented Jul 26, 2025

Test 10

Summary by CodeRabbit

  • New Features

    • Introduced a new admin interface for managing embeddable hosts, including adding, editing, and deleting allowed hosts and assigning them to categories.
    • Added new API endpoints and admin navigation for embedding settings.
    • Created new models, controllers, serializers, and database tables to support embeddable host management.
  • Improvements

    • Embeddable host validation and assignment are now handled via dedicated records rather than site settings.
    • Category assignment for embedded posts is now dynamic based on the host.
  • Bug Fixes

    • Enhanced hydration logic to support plural relationships in data models.
  • Documentation

    • Added and updated translation strings for new embedding features.
  • Tests

    • Added and updated tests for new models, controllers, and embedding logic.
  • Chores

    • Removed obsolete site settings and related code for embedding hosts and categories.

@coderabbitai
Copy link

coderabbitai bot commented Jul 26, 2025

Walkthrough

This change set introduces a new embeddable hosts management feature in the admin interface. It adds new models, controllers, serializers, database migrations, and JavaScript components to support CRUD operations for embeddable hosts, replacing previous site setting-based logic. Associated tests, routes, and localization entries are updated or added accordingly.

Changes

Cohort / File(s) Change Summary
Admin Embedding JS Feature
app/assets/javascripts/admin/adapters/embedding.js.es6, app/assets/javascripts/admin/components/embeddable-host.js.es6, app/assets/javascripts/admin/controllers/admin-embedding.js.es6, app/assets/javascripts/admin/routes/admin-embedding.js.es6, app/assets/javascripts/admin/routes/admin-route-map.js.es6, app/assets/javascripts/admin/templates/components/embeddable-host.hbs, app/assets/javascripts/admin/templates/customize.hbs, app/assets/javascripts/admin/templates/embedding.hbs
Adds adapter, component, controller, route, templates, and navigation for managing embeddable hosts in the admin UI.
REST Adapter & Model Hydration
app/assets/javascripts/discourse/adapters/rest.js.es6, app/assets/javascripts/discourse/models/store.js.es6
Updates admin model normalization and enhances embedded array hydration for related objects.
Backend: Controllers & Serializers
app/controllers/admin/embeddable_hosts_controller.rb, app/controllers/admin/embedding_controller.rb, app/serializers/embeddable_host_serializer.rb, app/serializers/embedding_serializer.rb
Introduces new controllers and serializers for embeddable hosts and embedding, supporting CRUD and data serialization.
Backend: Models & Logic
app/models/embeddable_host.rb, app/models/topic_embed.rb, app/models/topic.rb
Adds EmbeddableHost model, updates topic embedding logic to use per-host categories, and removes embeddable hosts check from topic expansion.
Legacy Logic Removal
app/models/site_setting.rb, config/site_settings.yml, config/locales/server.en.yml
Removes embeddable host and embed category site settings and related methods.
Routing
config/routes.rb
Adds admin routes for embedding management and embeddable hosts resources.
Database Migration
db/migrate/20150818190757_create_embeddable_hosts.rb
Creates embeddable_hosts table and migrates data from old site settings.
Localization
config/locales/client.en.yml
Adds new translation keys for embedding UI.
Embed Controller & Topic Retriever
app/controllers/embed_controller.rb, lib/topic_retriever.rb
Refactors host validation to use the new EmbeddableHost model.
Specs: Controller & Model
spec/controllers/admin/embeddable_hosts_controller_spec.rb, spec/controllers/admin/embedding_controller_spec.rb, spec/controllers/embed_controller_spec.rb, spec/models/embeddable_host_spec.rb, spec/models/topic_embed_spec.rb, spec/models/topic_spec.rb
Adds and updates tests for new controllers, models, and embedding logic.
Specs: Fabricators
spec/fabricators/category_fabricator.rb, spec/fabricators/embeddable_host_fabricator.rb
Replaces category fabricators with embeddable host fabricator and moves category fabricators to a new file.
Specs: Site Setting
spec/models/site_setting_spec.rb
Removes tests for deleted allows_embeddable_host? method.
JS Store and Test Helpers
test/javascripts/helpers/create-pretender.js.es6, test/javascripts/models/store-test.js.es6
Updates test data and assertions to support embedded array hydration and related color associations.

Sequence Diagram(s)

sequenceDiagram
    participant AdminUser
    participant AdminUI (Ember)
    participant API
    participant EmbeddableHost Model
    participant Database

    AdminUser->>AdminUI (Ember): Navigates to Embedding Admin Page
    AdminUI (Ember)->>API: GET /admin/customize/embedding
    API->>EmbeddableHost Model: Fetch all embeddable hosts
    EmbeddableHost Model->>Database: SELECT * FROM embeddable_hosts
    Database-->>EmbeddableHost Model: Hosts data
    EmbeddableHost Model-->>API: Hosts data
    API-->>AdminUI (Ember): JSON response with hosts
    AdminUI (Ember)-->>AdminUser: Renders host list

    AdminUser->>AdminUI (Ember): Adds/Edits/Deletes Host
    AdminUI (Ember)->>API: POST/PUT/DELETE /admin/embeddable_hosts
    API->>EmbeddableHost Model: Create/Update/Delete host
    EmbeddableHost Model->>Database: INSERT/UPDATE/DELETE
    Database-->>EmbeddableHost Model: Result
    EmbeddableHost Model-->>API: Updated hosts
    API-->>AdminUI (Ember): JSON response
    AdminUI (Ember)-->>AdminUser: Updates UI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

In the warren of code, a new path appears,
Hosts embeddable, managed without fears.
From settings to models, the logic now flows,
With tables and routes where the new data grows.
A hop, a skip, and tests all in line—
This rabbit’s quite proud of the embedding design! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rest-serializer-enhancement-post

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@everettbu
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jul 29, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

1 similar comment
@coderabbitai
Copy link

coderabbitai bot commented Jul 29, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (14)
spec/controllers/admin/embedding_controller_spec.rb (1)

4-4: Fix RuboCop style violations.

Remove the extra empty lines at the beginning and end of the describe block.

 describe Admin::EmbeddingController do
-
   it "is a subclass of AdminController" do
     expect(Admin::EmbeddingController < Admin::AdminController).to eq(true)
   end
-
 end

Also applies to: 8-8

spec/controllers/admin/embeddable_hosts_controller_spec.rb (1)

4-4: Fix RuboCop style violations.

Remove the extra empty lines consistent with the previous file.

 describe Admin::EmbeddableHostsController do
-
   it "is a subclass of AdminController" do
     expect(Admin::EmbeddableHostsController < Admin::AdminController).to eq(true)
   end
-
 end

Also applies to: 8-8

config/locales/client.en.yml (1)

2494-2501: Indentation & namespace sanity-check for the new embedding keys

The new embedding: block is added as a sibling to emoji: under admin_js.

  1. Ensure the 6-space indentation level is intentional so the full i18n path becomes js.admin_js.embedding.*.
  2. Run rake i18n:js:export (or the project-specific task) to verify there’s no collision with an existing admin_js.embedding namespace coming from plugins or core.
  3. Because YAML has no ordering guarantee, keeping related admin sections alphabetically sorted helps future merges.

No functional changes required—just make sure the file still passes yamllint and that the keys load in the Ember templates.

app/assets/javascripts/admin/routes/admin-embedding.js.es6 (1)

1-9: Unable to determine Ember Data version—please verify
I couldn’t locate your Ember or Ember Data versions in the repo. To confirm whether store.find() is deprecated (and should be replaced with store.findAll() or another modern API), please check your project’s Ember Data version (e.g. in package.json, yarn.lock, or ember-cli-build.js).

app/serializers/embeddable_host_serializer.rb (1)

1-16: Simplify by removing redundant attribute methods.

The serializer implementation is correct but can be simplified. ActiveModel::Serializer automatically creates methods for declared attributes, so the explicit methods are redundant.

 class EmbeddableHostSerializer < ApplicationSerializer
   attributes :id, :host, :category_id
-
-  def id
-    object.id
-  end
-
-  def host
-    object.host
-  end
-
-  def category_id
-    object.category_id
-  end
 end

The simplified version will have identical functionality since the serializer framework automatically creates these accessor methods based on the attributes declaration.

app/serializers/embedding_serializer.rb (1)

1-8: Consider removing redundant id method.

The id method on lines 5-7 is redundant since id is already declared in the attributes list on line 2. ActiveModelSerializers automatically handles the id attribute.

-  def id
-    object.id
-  end
spec/models/embeddable_host_spec.rb (1)

3-40: Fix formatting issues identified by RuboCop.

Remove extra empty lines in block bodies for consistent formatting.

 describe EmbeddableHost do
-
   it "trims http" do
     eh = EmbeddableHost.new(host: 'http://example.com')
     expect(eh).to be_valid
     expect(eh.host).to eq('example.com')
   end

   it "trims https" do
     eh = EmbeddableHost.new(host: 'https://example.com')
     expect(eh).to be_valid
     expect(eh.host).to eq('example.com')
   end

   it "trims paths" do
     eh = EmbeddableHost.new(host: 'https://example.com/1234/45')
     expect(eh).to be_valid
     expect(eh.host).to eq('example.com')
   end

   describe "allows_embeddable_host" do
     let!(:host) { Fabricate(:embeddable_host) }

     it 'works as expected' do
       expect(EmbeddableHost.host_allowed?('http://eviltrout.com')).to eq(true)
       expect(EmbeddableHost.host_allowed?('https://eviltrout.com')).to eq(true)
       expect(EmbeddableHost.host_allowed?('https://not-eviltrout.com')).to eq(false)
     end

     it 'works with multiple hosts' do
       Fabricate(:embeddable_host, host: 'discourse.org')
       expect(EmbeddableHost.host_allowed?('http://eviltrout.com')).to eq(true)
       expect(EmbeddableHost.host_allowed?('http://discourse.org')).to eq(true)
     end
-
   end
-
 end
app/assets/javascripts/admin/templates/embedding.hbs (1)

1-12: Consider moving inline styles to CSS classes for better maintainability.

The inline style attributes on table headers work but make styling harder to maintain and override. Consider defining CSS classes instead.

    <tr>
-      <th style='width: 50%'>{{i18n "admin.embedding.host"}}</th>
-      <th style='width: 30%'>{{i18n "admin.embedding.category"}}</th>
-      <th style='width: 20%'>&nbsp;</th>
+      <th class="host-column">{{i18n "admin.embedding.host"}}</th>
+      <th class="category-column">{{i18n "admin.embedding.category"}}</th>
+      <th class="actions-column">&nbsp;</th>
    </tr>

Then define the widths in your CSS file:

.host-column { width: 50%; }
.category-column { width: 30%; }
.actions-column { width: 20%; }
app/assets/javascripts/admin/templates/components/embeddable-host.hbs (1)

3-3: Consider adding accessibility attributes to the input field.

For better accessibility, consider adding an aria-label or associating the input with a label.

-    {{input value=buffered.host placeholder="example.com" enter="save" class="host-name"}}
+    {{input value=buffered.host placeholder="example.com" enter="save" class="host-name" aria-label="Host name"}}
app/controllers/admin/embedding_controller.rb (1)

15-20: Consider using a proper model instead of OpenStruct.

Using OpenStruct with a hardcoded ID for the embedding object is unconventional. Consider creating a proper model or service object for better maintainability.

  def fetch_embedding
-    @embedding = OpenStruct.new({
-      id: 'default',
-      embeddable_hosts: EmbeddableHost.all.order(:host)
-    })
+    @embedding = Embedding.new # or create a proper Embedding model/service
  end

Alternatively, if this is truly just a container for embeddable_hosts, document why OpenStruct is used here.

app/models/embeddable_host.rb (1)

10-18: Consider using conventional rescue syntax for better readability.

The method logic is solid with proper URI parsing and case-insensitive lookup. However, the rescue modifier form flagged by static analysis could be improved for better readability.

Apply this diff to use conventional rescue syntax:

  def self.record_for_host(host)
-   uri = URI(host) rescue nil
+   begin
+     uri = URI(host)
+   rescue
+     uri = nil
+   end
    return false unless uri.present?
db/migrate/20150818190757_create_embeddable_hosts.rb (1)

2-32: Consider breaking down the complex migration method.

The static analysis tool flagged the high ABC complexity (24.43/23). The method handles multiple concerns: table creation, data migration, and cleanup.

Consider extracting helper methods:

def change
  create_embeddable_hosts_table
  migrate_existing_data
  cleanup_old_settings
end

private

def create_embeddable_hosts_table
  create_table :embeddable_hosts, force: true do |t|
    t.string :host, null: false
    t.integer :category_id, null: false
    t.timestamps
  end
end

def migrate_existing_data
  category_id = resolve_category_id
  migrate_embeddable_hosts(category_id) if category_id > 0
end

def cleanup_old_settings
  execute "DELETE FROM site_settings WHERE name IN ('embeddable_hosts', 'embed_category')"
end
spec/models/topic_spec.rb (1)

1407-1407: Fix typo in context description.

-    describe 'with an emeddable host' do
+    describe 'with an embeddable host' do
app/assets/javascripts/admin/components/embeddable-host.js.es6 (1)

30-41: Consider improving category handling in save action.

The save action works correctly but has a potential issue with direct model manipulation.

      const host = this.get('host');
      host.save(props).then(() => {
-        host.set('category', Discourse.Category.findById(this.get('categoryId')));
+        // Let the model handle category relationship updates through its response
+        // or refresh the model to get updated relationships
        this.set('editToggled', false);
      }).catch(popupAjaxError);

Alternatively, ensure the server response includes the updated category relationship to avoid manual model manipulation.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 913c3d6 and d1c6918.

📒 Files selected for processing (36)
  • app/assets/javascripts/admin/adapters/embedding.js.es6 (1 hunks)
  • app/assets/javascripts/admin/components/embeddable-host.js.es6 (1 hunks)
  • app/assets/javascripts/admin/controllers/admin-embedding.js.es6 (1 hunks)
  • app/assets/javascripts/admin/routes/admin-embedding.js.es6 (1 hunks)
  • app/assets/javascripts/admin/routes/admin-route-map.js.es6 (1 hunks)
  • app/assets/javascripts/admin/templates/components/embeddable-host.hbs (1 hunks)
  • app/assets/javascripts/admin/templates/customize.hbs (1 hunks)
  • app/assets/javascripts/admin/templates/embedding.hbs (1 hunks)
  • app/assets/javascripts/discourse/adapters/rest.js.es6 (2 hunks)
  • app/assets/javascripts/discourse/models/store.js.es6 (1 hunks)
  • app/controllers/admin/embeddable_hosts_controller.rb (1 hunks)
  • app/controllers/admin/embedding_controller.rb (1 hunks)
  • app/controllers/embed_controller.rb (1 hunks)
  • app/models/embeddable_host.rb (1 hunks)
  • app/models/site_setting.rb (0 hunks)
  • app/models/topic.rb (1 hunks)
  • app/models/topic_embed.rb (1 hunks)
  • app/serializers/embeddable_host_serializer.rb (1 hunks)
  • app/serializers/embedding_serializer.rb (1 hunks)
  • config/locales/client.en.yml (1 hunks)
  • config/locales/server.en.yml (0 hunks)
  • config/routes.rb (2 hunks)
  • config/site_settings.yml (0 hunks)
  • db/migrate/20150818190757_create_embeddable_hosts.rb (1 hunks)
  • lib/topic_retriever.rb (1 hunks)
  • spec/controllers/admin/embeddable_hosts_controller_spec.rb (1 hunks)
  • spec/controllers/admin/embedding_controller_spec.rb (1 hunks)
  • spec/controllers/embed_controller_spec.rb (3 hunks)
  • spec/fabricators/category_fabricator.rb (1 hunks)
  • spec/fabricators/embeddable_host_fabricator.rb (1 hunks)
  • spec/models/embeddable_host_spec.rb (1 hunks)
  • spec/models/site_setting_spec.rb (0 hunks)
  • spec/models/topic_embed_spec.rb (2 hunks)
  • spec/models/topic_spec.rb (3 hunks)
  • test/javascripts/helpers/create-pretender.js.es6 (2 hunks)
  • test/javascripts/models/store-test.js.es6 (1 hunks)
💤 Files with no reviewable changes (4)
  • config/site_settings.yml
  • app/models/site_setting.rb
  • spec/models/site_setting_spec.rb
  • config/locales/server.en.yml
🧰 Additional context used
🧬 Code Graph Analysis (10)
app/models/topic_embed.rb (1)
app/models/embeddable_host.rb (1)
  • record_for_host (10-18)
app/models/embeddable_host.rb (1)
app/models/topic_embed.rb (1)
  • belongs_to (3-163)
spec/models/embeddable_host_spec.rb (1)
app/models/embeddable_host.rb (1)
  • host_allowed? (20-22)
app/serializers/embeddable_host_serializer.rb (1)
app/serializers/embedding_serializer.rb (2)
  • attributes (1-8)
  • id (5-7)
app/serializers/embedding_serializer.rb (1)
app/serializers/embeddable_host_serializer.rb (2)
  • attributes (1-15)
  • id (4-6)
app/controllers/embed_controller.rb (1)
app/models/embeddable_host.rb (1)
  • host_allowed? (20-22)
spec/models/topic_spec.rb (1)
app/models/topic.rb (1)
  • expandable_first_post? (868-870)
app/controllers/admin/embedding_controller.rb (2)
app/controllers/admin/embeddable_hosts_controller.rb (2)
  • before_filter (1-34)
  • update (9-12)
app/controllers/application_controller.rb (1)
  • render_serialized (238-240)
lib/topic_retriever.rb (1)
app/models/embeddable_host.rb (1)
  • host_allowed? (20-22)
app/controllers/admin/embeddable_hosts_controller.rb (3)
app/controllers/admin/embedding_controller.rb (2)
  • before_filter (1-21)
  • update (9-11)
app/serializers/embeddable_host_serializer.rb (2)
  • host (8-10)
  • category_id (12-14)
app/controllers/application_controller.rb (3)
  • success_json (362-364)
  • render_serialized (238-240)
  • render_json_error (357-360)
🪛 RuboCop (1.76.1)
spec/controllers/admin/embeddable_hosts_controller_spec.rb

[convention] 4-5: Extra empty line detected at block body beginning.

(Layout/EmptyLinesAroundBlockBody)


[convention] 8-9: Extra empty line detected at block body end.

(Layout/EmptyLinesAroundBlockBody)

spec/controllers/admin/embedding_controller_spec.rb

[convention] 4-5: Extra empty line detected at block body beginning.

(Layout/EmptyLinesAroundBlockBody)


[convention] 8-9: Extra empty line detected at block body end.

(Layout/EmptyLinesAroundBlockBody)

app/models/embeddable_host.rb

[convention] 11-11: Avoid using rescue in its modifier form.

(Style/RescueModifier)

spec/models/embeddable_host_spec.rb

[convention] 4-5: Extra empty line detected at block body beginning.

(Layout/EmptyLinesAroundBlockBody)


[convention] 37-38: Extra empty line detected at block body end.

(Layout/EmptyLinesAroundBlockBody)


[convention] 39-40: Extra empty line detected at block body end.

(Layout/EmptyLinesAroundBlockBody)

db/migrate/20150818190757_create_embeddable_hosts.rb

[convention] 2-32: Assignment Branch Condition size for change is too high. [<7, 22, 8> 24.43/23]

(Metrics/AbcSize)

🔇 Additional comments (45)
app/assets/javascripts/admin/routes/admin-route-map.js.es6 (1)

30-30: LGTM! Clean route integration.

The new adminEmbedding route is properly nested under adminCustomize and follows the established naming conventions. The /embedding path is descriptive and fits well within the admin customization section.

app/assets/javascripts/admin/templates/customize.hbs (1)

8-8: LGTM! Well-integrated navigation item.

The new embedding navigation item is appropriately placed after permalinks and follows the established pattern using proper internationalization keys. The integration maintains consistency with the existing admin navigation structure.

spec/models/topic_embed_spec.rb (2)

15-15: Good test setup for embeddable host integration.

Adding the embeddable_host fabricator properly sets up the test context for the new embeddable hosts functionality.


38-38: Migration from site settings to embeddable hosts verified

The two migration files properly handle the behavioral change:

  • db/migrate/20150609163211_migrate_embeddable_host.rb
    – Renames the old embeddable_host site setting to embeddable_hosts.
  • db/migrate/20150818190757_create_embeddable_hosts.rb
    – Creates the embeddable_hosts table.
    – Migrates existing values from embed_category and embeddable_hosts site settings into the new table.
    – Deletes the old site settings once data has been imported.

The test in spec/models/topic_embed_spec.rb correctly asserts that post.topic.category now comes from embeddable_host.category. No further action is needed.

app/assets/javascripts/admin/adapters/embedding.js.es6 (1)

3-7: Confirm the adapter path matches the server‐side route

pathFor() is hard-coded to "/admin/customize/embedding". Double-check that every CRUD route implemented on the Rails side is indeed nested under this exact prefix (e.g. GET /admin/customize/embedding, PUT /admin/customize/embedding/:id, …). If the server ended up under /admin/embedding or /admin/customize/embeddable_hosts, requests will 404.
If the endpoint name drifts later, consider pulling the path string from a shared constant to prevent silent breakage.

app/models/topic.rb (1)

868-870: approve expandable_first_post? simplification

All existing tests for expandable_first_post? still pass under every scenario—no embeddable host (false), with an embeddable host and valid embed_truncate/has_topic_embed? (true), and when either condition is false (false). Host validation now lives in the EmbeddableHost model powering TopicEmbed, so removing the extra SiteSetting.embeddable_hosts.present? check is safe.

lib/topic_retriever.rb (1)

15-17: LGTM! Clean migration from site setting to model-based host validation.

The replacement of SiteSetting.allows_embeddable_host?(@embed_url) with EmbeddableHost.host_allowed?(@embed_url) is a good architectural improvement. Moving host validation logic from site settings to a dedicated model provides better separation of concerns and enables more sophisticated host management.

The method signature and return type remain consistent (boolean), making this a clean drop-in replacement.

app/assets/javascripts/discourse/adapters/rest.js.es6 (2)

1-1: LGTM! Addition supports the new embeddable host admin feature.

Adding 'embeddable-host' to the ADMIN_MODELS array is necessary to enable admin routing for the new embeddable host management functionality.


22-24: Excellent improvement! Type normalization prevents routing issues.

The addition of type.replace('_', '-') before checking ADMIN_MODELS is a smart improvement that ensures consistent type matching. This prevents issues where Ember might use underscores in type names (e.g., embeddable_host) while the constant uses hyphens (embeddable-host).

This normalization will benefit not just the new embeddable host feature but also ensure robust type checking for all admin models.

app/models/topic_embed.rb (1)

36-37: LGTM! Clean integration with EmbeddableHost model.

The code correctly retrieves the embeddable host record for the URL using the new model method.

test/javascripts/models/store-test.js.es6 (2)

109-121: LGTM! Good test coverage for embedded array functionality.

The test properly validates the new colors array hydration and the assertion style improvement using the assert parameter is good practice.


123-136: LGTM! Comprehensive validation of embedded arrays in collections.

The test correctly verifies that embedded arrays are properly hydrated in findAll results, ensuring the colors array contains the expected objects with correct IDs.

app/controllers/embed_controller.rb (1)

61-61: LGTM! Clean delegation to EmbeddableHost model.

The simplified validation using EmbeddableHost.host_allowed? is much cleaner than the previous site setting-based approach and properly separates concerns.

app/serializers/embedding_serializer.rb (1)

3-3: LGTM! Appropriate serialization strategy for embeddable hosts.

Using embed: :ids for the has_many relationship is efficient and follows Rails serialization best practices.

spec/models/embeddable_host_spec.rb (2)

5-21: LGTM! Comprehensive test coverage for host normalization.

The tests thoroughly validate the host normalization behavior, covering HTTP/HTTPS prefix removal and path trimming. This ensures the model correctly standardizes host input.


23-38: LGTM! Good test coverage for host_allowed? method.

The tests properly validate both single and multiple host scenarios, ensuring the host_allowed? method works correctly in different configurations.

app/assets/javascripts/admin/templates/embedding.hbs (1)

14-14: LGTM - Button implementation follows Discourse patterns.

The d-button component usage with proper localization, icon, and CSS class follows Discourse conventions correctly.

app/assets/javascripts/admin/templates/components/embeddable-host.hbs (1)

1-19: LGTM - Well-structured component template with proper state management.

The template correctly handles both editing and display states, uses appropriate Discourse components, and implements proper disabled states for buttons during save operations.

app/assets/javascripts/admin/controllers/admin-embedding.js.es6 (2)

5-7: Clarify the purpose of saveChanges with empty object.

The saveChanges action calls update({}) with an empty object, which seems unusual. This might not persist any actual changes.

Please verify if this is the intended behavior or if specific properties should be updated. Consider whether this action should:

  1. Save actual changes to embedding properties
  2. Trigger a refresh of the data
  3. Be removed if not needed

9-12: LGTM - Host creation follows standard Ember Data patterns.

The addHost action correctly creates a new record and adds it to the collection.

config/routes.rb (2)

138-139: LGTM - Embedding routes follow RESTful conventions.

The GET and PUT routes for embedding management are properly constrained with AdminConstraint and follow standard RESTful patterns.


153-153: LGTM - Embeddable hosts resource route is properly configured.

The embeddable_hosts resource route with AdminConstraint provides standard CRUD operations and follows Discourse routing patterns.

test/javascripts/helpers/create-pretender.js.es6 (3)

42-44: LGTM! Data structure enhanced to support plural embedded relationships.

The addition of color_ids arrays to the fruits data structure properly supports the new plural hydration feature introduced in the store. This enables testing of the enhanced _hydrateEmbedded method that can handle arrays of related objects.


49-51: LGTM! Colors reference data added for hydration support.

The new colors array provides the necessary reference data to support hydration of the color_ids arrays. The structure with id and name properties is appropriate for testing the enhanced embedding capabilities.


228-228: LGTM! API responses updated to include colors for hydration testing.

The inclusion of the colors array in both GET endpoints ensures that the enhanced hydration logic has access to all necessary reference data when processing the color_ids arrays in the fruits data.

Also applies to: 232-232

app/models/embeddable_host.rb (3)

1-3: LGTM! Model definition with appropriate validation and association.

The hostname validation regex properly handles domain names with optional ports and paths, and the category association aligns with the embedding feature requirements.


5-8: LGTM! Host normalization logic is appropriate.

The before_validation callback properly normalizes host strings by removing HTTP/HTTPS schemes and path components, ensuring consistent storage format. The use of sub! for in-place modification is efficient.


20-22: LGTM! Clean convenience method for host validation.

The host_allowed? method provides a clear boolean interface for checking host permissions, appropriately delegating to record_for_host.

spec/controllers/embed_controller_spec.rb (2)

21-21: LGTM! Tests properly updated to use the new EmbeddableHost model.

The transition from site setting manipulation to using Fabricate(:embeddable_host) correctly reflects the architectural change. The multiple host test case with various formats (HTTP, HTTPS, with paths) provides good coverage of the new model's capabilities.

Also applies to: 33-33, 68-70


74-96: LGTM! Comprehensive test coverage maintained with new model approach.

The test scenarios properly verify both successful embedding with various host formats and rejection of unauthorized hosts. The edge case testing for paths and protocols ensures robust validation of the new embeddable host logic.

app/assets/javascripts/discourse/models/store.js.es6 (2)

192-192: LGTM! Regex pattern enhanced to support plural embedded relationships.

The modification to capture both _id and _ids patterns is well-designed, maintaining backward compatibility while enabling the new plural hydration capability. The optional capture group (s?) cleanly distinguishes between singular and plural cases.


196-209: LGTM! Hydration logic properly enhanced for plural relationships.

The implementation correctly handles both singular and plural embedded relationships:

  • Plural case maps over ID arrays and assigns to pluralized property names
  • Singular case maintains existing behavior
  • Clean separation of logic based on the captured 's' group

This enhancement enables the new embeddable hosts functionality while preserving backward compatibility.

app/controllers/admin/embeddable_hosts_controller.rb (2)

1-3: LGTM! Proper controller setup with appropriate inheritance and filters.

The controller correctly inherits from Admin::AdminController and uses standard authentication/authorization filters. The setup follows Rails conventions for admin controllers.


1-34: Overall solid controller structure with Rails best practices.

The controller demonstrates good separation of concerns with the shared save_host method, follows Rails conventions, and uses appropriate parent controller methods like render_serialized and success_json. The JSON response patterns are consistent throughout.

db/migrate/20150818190757_create_embeddable_hosts.rb (1)

3-7: LGTM! Table structure is well-defined.

The table schema is appropriate with proper null constraints and timestamp fields.

spec/models/topic_spec.rb (4)

241-241: LGTM! Good cleanup of unused variable.

Removing the unused topic variable improves code quality.


250-250: LGTM! Good cleanup of unused variable.

Removing the unused topic variable improves code quality.


1408-1412: LGTM! Proper test setup for embeddable host feature.

The test setup correctly uses the new EmbeddableHost fabricator and configures the necessary settings and stubs for testing the expandable_first_post? behavior.


1414-1426: LGTM! Comprehensive test coverage for expandable_first_post.

The test cases properly cover all the conditions required for the method to return true/false, including:

  • Correct settings and topic_embed (should be true)
  • embed_truncate disabled (should be false)
  • has_topic_embed disabled (should be false)
app/assets/javascripts/admin/components/embeddable-host.js.es6 (6)

1-5: LGTM! Proper imports for Ember component functionality.

The imports correctly include necessary mixins, decorators, and error handling utilities.


6-11: LGTM! Clean component setup with proper mixin usage.

The component correctly extends with bufferedProperty mixin and sets up initial state properties.


13-17: LGTM! Proper focus management implementation.

The use of Ember.run.schedule('afterRender') ensures DOM elements are available before focusing, which is the correct approach for Ember components.


19-22: LGTM! Well-implemented validation logic.

The cantSave computed property correctly prevents saving when the host is being saved or when the host field is empty.


43-51: LGTM! Proper confirmation dialog and error handling.

The delete action correctly prompts for confirmation and handles the deletion with proper cleanup through the parent action.


53-61: LGTM! Clean cancel logic for both new and existing hosts.

The cancel action properly handles both scenarios: deleting new unsaved hosts and rolling back changes for existing hosts.

Comment on lines +14 to +16
deleteHost(host) {
this.get('embedding.embeddable_hosts').removeObject(host);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider destroying the host record instead of just removing from collection.

The deleteHost action only removes the host from the local collection but doesn't destroy the record on the server. This could lead to data inconsistency.

    deleteHost(host) {
-      this.get('embedding.embeddable_hosts').removeObject(host);
+      host.destroy().then(() => {
+        this.get('embedding.embeddable_hosts').removeObject(host);
+      }).catch(error => {
+        // Handle error appropriately
+        console.error('Failed to delete host:', error);
+      });
    }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In app/assets/javascripts/admin/controllers/admin-embedding.js.es6 around lines
14 to 16, the deleteHost method currently only removes the host from the local
embeddable_hosts collection without destroying the record on the server. To fix
this, update the deleteHost method to call the destroyRecord() method on the
host object, which will delete the record on the server and then remove it from
the collection to maintain data consistency.

Comment on lines +9 to +18
def update
host = EmbeddableHost.where(id: params[:id]).first
save_host(host)
end

def destroy
host = EmbeddableHost.where(id: params[:id]).first
host.destroy
render json: success_json
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for missing records.

The update and destroy actions don't handle cases where the embeddable host record doesn't exist. Using .first returns nil for missing records, which could lead to NoMethodError when calling methods on nil.

Apply this diff to add proper error handling:

  def update
    host = EmbeddableHost.where(id: params[:id]).first
+   return render_json_error("Not found", status: 404) unless host
    save_host(host)
  end

  def destroy
    host = EmbeddableHost.where(id: params[:id]).first
+   return render_json_error("Not found", status: 404) unless host
    host.destroy
    render json: success_json
  end

Alternatively, use .find instead of .where(...).first to automatically raise ActiveRecord::RecordNotFound:

  def update
-   host = EmbeddableHost.where(id: params[:id]).first
+   host = EmbeddableHost.find(params[:id])
    save_host(host)
  end

  def destroy
-   host = EmbeddableHost.where(id: params[:id]).first
+   host = EmbeddableHost.find(params[:id])
    host.destroy
    render json: success_json
  end
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def update
host = EmbeddableHost.where(id: params[:id]).first
save_host(host)
end
def destroy
host = EmbeddableHost.where(id: params[:id]).first
host.destroy
render json: success_json
end
def update
host = EmbeddableHost.where(id: params[:id]).first
return render_json_error("Not found", status: 404) unless host
save_host(host)
end
def destroy
host = EmbeddableHost.where(id: params[:id]).first
return render_json_error("Not found", status: 404) unless host
host.destroy
render json: success_json
end
🤖 Prompt for AI Agents
In app/controllers/admin/embeddable_hosts_controller.rb around lines 9 to 18,
the update and destroy actions fetch the embeddable host using
`.where(...).first`, which returns nil if the record is missing, causing
potential NoMethodError when calling methods on nil. Replace `.where(id:
params[:id]).first` with `.find(params[:id])` to let ActiveRecord automatically
raise RecordNotFound exceptions for missing records, or add explicit nil checks
and handle the error by rendering an appropriate error response before
proceeding.

Comment on lines +22 to +32
def save_host(host)
host.host = params[:embeddable_host][:host]
host.category_id = params[:embeddable_host][:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?

if host.save
render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
else
render_json_error(host)
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using strong parameters for better security.

The save_host method handles success/error responses appropriately, but directly accessing params[:embeddable_host][:host] without strong parameters could be a security risk.

Apply this diff to use strong parameters:

  protected

    def save_host(host)
-     host.host = params[:embeddable_host][:host]
-     host.category_id = params[:embeddable_host][:category_id]
+     permitted_params = params.require(:embeddable_host).permit(:host, :category_id)
+     host.host = permitted_params[:host]
+     host.category_id = permitted_params[:category_id]
      host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?

      if host.save
        render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
      else
        render_json_error(host)
      end
    end

Or more concisely using assign_attributes:

    def save_host(host)
+     permitted_params = params.require(:embeddable_host).permit(:host, :category_id)
-     host.host = params[:embeddable_host][:host]
-     host.category_id = params[:embeddable_host][:category_id]
+     host.assign_attributes(permitted_params)
      host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def save_host(host)
host.host = params[:embeddable_host][:host]
host.category_id = params[:embeddable_host][:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?
if host.save
render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
else
render_json_error(host)
end
end
def save_host(host)
permitted_params = params.require(:embeddable_host).permit(:host, :category_id)
host.host = permitted_params[:host]
host.category_id = permitted_params[:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?
if host.save
render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
else
render_json_error(host)
end
end
🤖 Prompt for AI Agents
In app/controllers/admin/embeddable_hosts_controller.rb around lines 22 to 32,
the save_host method directly accesses params without using strong parameters,
which is a security risk. Define a private method to whitelist the allowed
parameters from params[:embeddable_host], then use host.assign_attributes with
these strong parameters instead of directly assigning each attribute. This will
ensure only permitted attributes are assigned and improve security.

Comment on lines +9 to +11
def update
render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true)
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update action doesn't perform any updates.

The update action renders the same data as show without performing any actual updates. This seems incorrect for a PUT endpoint.

Consider implementing actual update logic or removing this action if updates aren't needed:

  def update
+    # Add update logic here if needed, e.g.:
+    # @embedding.some_property = params[:some_param]
+    # @embedding.save
    render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true)
  end

Or if no updates are needed, consider removing the update route and action entirely.

🤖 Prompt for AI Agents
In app/controllers/admin/embedding_controller.rb around lines 9 to 11, the
update action currently does not perform any update operation and just renders
the existing embedding data. To fix this, implement the update logic by applying
permitted parameters to update the @embedding object and handle success or
failure responses accordingly. If updating embeddings is not required, remove
the update action and its corresponding route to avoid confusion and incorrect
API behavior.

def fetch_embedding
@embedding = OpenStruct.new({
id: 'default',
embeddable_hosts: EmbeddableHost.all.order(:host)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Database query lacks error handling.

The EmbeddableHost.all.order(:host) query could potentially fail or return unexpected results.

Consider adding error handling and possibly scoping:

-      embeddable_hosts: EmbeddableHost.all.order(:host)
+      embeddable_hosts: EmbeddableHost.all.order(:host) rescue []

Or better yet, move this to a service method with proper error handling.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
embeddable_hosts: EmbeddableHost.all.order(:host)
embeddable_hosts: EmbeddableHost.all.order(:host) rescue []
🤖 Prompt for AI Agents
In app/controllers/admin/embedding_controller.rb at line 18, the database query
EmbeddableHost.all.order(:host) lacks error handling which could cause unhandled
exceptions or unexpected results. Refactor this by moving the query into a
dedicated service method that wraps the call in error handling logic, such as
rescuing potential exceptions and returning a safe fallback or logging the
error. Then call this service method from the controller instead of directly
querying the model.

Comment on lines +24 to +26
records.each do |h|
execute "INSERT INTO embeddable_hosts (host, category_id, created_at, updated_at) VALUES ('#{h}', #{category_id}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security vulnerability: SQL injection risk.

Using string interpolation directly in SQL statements creates a SQL injection vulnerability.

-          records.each do |h|
-            execute "INSERT INTO embeddable_hosts (host, category_id, created_at, updated_at) VALUES ('#{h}', #{category_id}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
-          end
+          records.each do |h|
+            execute sanitize_sql(["INSERT INTO embeddable_hosts (host, category_id, created_at, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)", h, category_id])
+          end

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In db/migrate/20150818190757_create_embeddable_hosts.rb around lines 24 to 26,
the code uses string interpolation to insert values directly into the SQL
statement, which poses a SQL injection risk. To fix this, replace the string
interpolation with parameterized queries or use ActiveRecord's built-in methods
to safely insert the records, ensuring that user input is properly escaped and
not directly concatenated into the SQL string.

Comment on lines +5 to +7
it "is a subclass of AdminController" do
expect(Admin::EmbeddableHostsController < Admin::AdminController).to eq(true)
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Insufficient test coverage for CRUD controller.

This controller handles CRUD operations (create, update, destroy) for EmbeddableHost records, but the test only verifies inheritance. You need comprehensive tests for:

  • Creating embeddable hosts with valid/invalid data
  • Updating existing hosts
  • Deleting hosts and handling dependencies
  • Authorization checks for admin-only access
  • Proper JSON responses and error handling
 describe Admin::EmbeddableHostsController do
+  let(:admin) { Fabricate(:admin) }
+  let(:embeddable_host) { Fabricate(:embeddable_host) }
+
+  before do
+    sign_in(admin)
+  end

   it "is a subclass of AdminController" do
     expect(Admin::EmbeddableHostsController < Admin::AdminController).to eq(true)
   end
+
+  describe '#create' do
+    it 'creates a new embeddable host' do
+      post :create, params: { embeddable_host: { host: 'example.com' } }
+      expect(response).to be_success
+      expect(EmbeddableHost.count).to eq(1)
+    end
+
+    it 'handles validation errors' do
+      post :create, params: { embeddable_host: { host: '' } }
+      expect(response).to have_http_status(:unprocessable_entity)
+    end
+  end
+
+  describe '#update' do
+    it 'updates an existing embeddable host' do
+      put :update, params: { id: embeddable_host.id, embeddable_host: { host: 'updated.com' } }
+      expect(response).to be_success
+      expect(embeddable_host.reload.host).to eq('updated.com')
+    end
+  end
+
+  describe '#destroy' do
+    it 'deletes an embeddable host' do
+      delete :destroy, params: { id: embeddable_host.id }
+      expect(response).to be_success
+      expect(EmbeddableHost.exists?(embeddable_host.id)).to be_false
+    end
+  end
 end
🤖 Prompt for AI Agents
In spec/controllers/admin/embeddable_hosts_controller_spec.rb around lines 5 to
7, the test only checks that the controller inherits from AdminController but
lacks coverage for its CRUD actions. Add tests for creating embeddable hosts
with both valid and invalid data, updating existing hosts, deleting hosts
including dependency handling, verifying admin-only authorization, and ensuring
correct JSON responses and error handling for each action.

Comment on lines +5 to +7
it "is a subclass of AdminController" do
expect(Admin::EmbeddingController < Admin::AdminController).to eq(true)
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Insufficient test coverage for a new admin controller.

This test only verifies inheritance but doesn't test the actual controller functionality. For a new admin controller that handles embedding data with show and update actions, you should add tests for:

  • Authentication and authorization requirements
  • Successful responses for valid requests
  • Error handling for invalid data
  • Proper serialization of embedding data
 describe Admin::EmbeddingController do
+  let(:admin) { Fabricate(:admin) }
+
+  before do
+    sign_in(admin)
+  end

   it "is a subclass of AdminController" do
     expect(Admin::EmbeddingController < Admin::AdminController).to eq(true)
   end
+
+  describe '#show' do
+    it 'returns embedding data' do
+      get :show
+      expect(response).to be_success
+      expect(response.content_type).to eq('application/json')
+    end
+  end
+
+  describe '#update' do
+    it 'updates embedding settings successfully' do
+      put :update, params: { embedding: { some_setting: 'value' } }
+      expect(response).to be_success
+    end
+  end
 end
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it "is a subclass of AdminController" do
expect(Admin::EmbeddingController < Admin::AdminController).to eq(true)
end
describe Admin::EmbeddingController do
let(:admin) { Fabricate(:admin) }
before do
sign_in(admin)
end
it "is a subclass of AdminController" do
expect(Admin::EmbeddingController < Admin::AdminController).to eq(true)
end
describe '#show' do
it 'returns embedding data' do
get :show
expect(response).to be_success
expect(response.content_type).to eq('application/json')
end
end
describe '#update' do
it 'updates embedding settings successfully' do
put :update, params: { embedding: { some_setting: 'value' } }
expect(response).to be_success
end
end
end
🤖 Prompt for AI Agents
In spec/controllers/admin/embedding_controller_spec.rb around lines 5 to 7, the
current test only checks inheritance and lacks coverage for the controller's
functionality. Add tests to verify authentication and authorization for
accessing the controller actions, ensure the show and update actions return
successful responses with valid requests, test error handling for invalid input
data, and confirm that the embedding data is properly serialized in the
responses.

Comment on lines +1 to 4
Fabricator(:embeddable_host) do
host "eviltrout.com"
category
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect file content - this appears to be misplaced.

This file is named category_fabricator.rb but only contains an embeddable_host fabricator. According to the AI summary, category fabricators should have been moved to spec/fabricators/embeddable_host_fabricator.rb, not completely removed from this file.

The content in this file should likely be:

  • Category fabricators (:category, :diff_category, :happy_category, :private_category)
  • NOT the embeddable_host fabricator which belongs in its own file

Please verify the file contents and ensure fabricators are in their correct locations.

🤖 Prompt for AI Agents
In spec/fabricators/category_fabricator.rb lines 1 to 4, the file incorrectly
contains the embeddable_host fabricator instead of category fabricators. Remove
the embeddable_host fabricator from this file and move it to
spec/fabricators/embeddable_host_fabricator.rb. Then, add the appropriate
category fabricators (:category, :diff_category, :happy_category,
:private_category) to this file to ensure fabricators are organized by their
correct domain.

Comment on lines +1 to +27
Fabricator(:category) do
name { sequence(:name) { |n| "Amazing Category #{n}" } }
user
end

Fabricator(:diff_category, from: :category) do
name "Different Category"
user
end

Fabricator(:happy_category, from: :category) do
name 'Happy Category'
slug 'happy'
user
end

Fabricator(:private_category, from: :category) do
transient :group

name 'Private Category'
slug 'private'
user
after_build do |cat, transients|
cat.update!(read_restricted: true)
cat.category_groups.build(group_id: transients[:group].id, permission_type: CategoryGroup.permission_types[:full])
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

File naming inconsistency - contains category fabricators, not embeddable_host fabricators.

This file is named embeddable_host_fabricator.rb but contains category fabricators (:category, :diff_category, :happy_category, :private_category). Based on the filename, it should contain embeddable_host fabricators.

The file organization should be:

  • spec/fabricators/category_fabricator.rb should contain these category fabricators
  • spec/fabricators/embeddable_host_fabricator.rb should contain the embeddable_host fabricator currently in the category_fabricator.rb file

Please correct the file organization to match their intended contents.

🤖 Prompt for AI Agents
In spec/fabricators/embeddable_host_fabricator.rb lines 1 to 27, the file
contains category fabricators instead of embeddable_host fabricators. Move all
category fabricator definitions (:category, :diff_category, :happy_category,
:private_category) to a new or existing file named
spec/fabricators/category_fabricator.rb. Then, move the embeddable_host
fabricator code currently in category_fabricator.rb into
embeddable_host_fabricator.rb to ensure each file contains fabricators matching
its name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants