-
Notifications
You must be signed in to change notification settings - Fork 8.6k
DEV: Refactor themes controller to services part 1 #29631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DEV: Refactor themes controller to services part 1 #29631
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is still a draft, but I left some comments, some are just me thinking out loud, I’ll be glad to get your feedback 😁
private | ||
|
||
def ban_in_allowlist_mode | ||
Theme.allowed_remote_theme_ids.nil? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can’t be an empty array? It looks like it should return an array 😅 We could maybe use #blank?
instead of #nil?
just to be sure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's weird, sometimes it's nil and sometimes it's an empty array...but yes I think blank could work here
Lines 258 to 265 in dd4755b
def self.allowed_remote_theme_ids | |
return nil if GlobalSetting.allowed_theme_repos.blank? | |
get_set_cache "allowed_remote_theme_ids" do | |
urls = GlobalSetting.allowed_theme_repos.split(",").map(&:strip) | |
Theme.joins(:remote_theme).where("remote_themes.remote_url in (?)", urls).pluck(:id) | |
end | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annoyingly this return nil
seems to be important, if Theme.joins(:remote_theme).where("remote_themes.remote_url in (?)", urls).pluck(:id)
returns an [] we don't care for the purposes of other existing code. Not sure if that's intentional or not, don't want to touch it for now
@martin-brennan ok, so now that #29660 has been merged, we can do this (just tested locally, did not a lot of tests though, but it’s working): transaction do
try(Theme::InvalidFieldTargetError, Theme::InvalidFieldTypeError) do
model :theme, :create_theme
end
step :update_default_theme
step :log_theme_change
end
def create_theme(params:)
Theme.create(params.slice(:name, :user_id, :user_selectable, :color_scheme_id, :component)) do |theme|
params.theme_fields.to_a.each { |field| theme.set_field(**field.symbolize_keys) }
end
end Instead of having 3 steps with their own error logic/handling, we just use one and everything’s covered 😁 In the controller, I see that everything’s matched through |
Nice that's great @Flink thanks for letting me know, will do some further refactors with this now 👍 Also I need to go and make service specs for all the services I've added 😅 The functionality is covered by controller specs but I still want the low level ones too |
Great! Let me know if you need a hand or when you want another review 😁 |
This pull request has been automatically marked as stale because it has been open for 60 days with no activity. To keep it open, remove the stale tag, push code, or add a comment. Otherwise, it will be closed in 14 days. |
This pull request has been automatically marked as stale because it has been open for 60 days with no activity. To keep it open, remove the stale tag, push code, or add a comment. Otherwise, it will be closed in 14 days. |
@Flink okay it's been a few months 😅 But this is finally done now I think, can you please re-review? |
@Flink another bump here, can you please take a look? |
Yes sorry, completely forgot, as you're on vacation I thought it wasn't that urgent 😅 |
@Flink it's okay, not super urgent, as long as it's in your queue somewhere, I just couldn't tell whether you got the first ping, I thought you might have been on vacation when I did it :) |
No worries, it's definitely in my queue 😉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see some more services 👍 😁
Nothing too bad in my comments, mainly suggestions/improvements.
policy :ensure_remote_themes_are_not_allowlisted | ||
|
||
transaction do | ||
try(Theme::InvalidFieldTargetError, Theme::InvalidFieldTypeError) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following a recent change to the model
step (you’ll need to rebase this PR against main, though), we don’t need this try
block anymore. If an exception is raised inside a model
step, the step will fail and can be matched with the on_model_not_found
outcome.
In the controller, it seems we weren’t catching this exception, but I guess we should probably match the on_model_not_found
outcome.
end | ||
|
||
it "clears the existing default theme" do | ||
existing_default = Fabricate(:theme) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could extract this in a before block.
it "clears the existing default theme" do | ||
existing_default = Fabricate(:theme) | ||
existing_default.set_default! | ||
expect(existing_default.default?).to eq(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think this expectation is really useful, #set_default!
is tested elsewhere and should be working, so that’s not the responsibility of this spec to ensure that.
|
||
expect(result).to be_a_success | ||
expect(result.theme.default?).to eq(true) | ||
expect(existing_default.reload.default?).to eq(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could probably check directly the change happens as expected:
expect { result }.to change { existing_default.reload.default? }.to false
Then we could verify that the new theme is indeed marked as being the default one.
As seen in the advanced search filters... iOS doesn't show placeholders for the date input, so we have a CSS adjustment for this, but it doesn't clear when a value is present. This update adds a class when a value is present so the placeholder can be cleared. Before:  After:  Also fixed extra left margin by removing a class.
These lines of code would output "Period - Site name" as the page title for the crawlier view only for Top routes. This is too specific and unnecessary, since the top route isn't highly prioritized for crawlers. Without this, the page title defaults to "Site name" for these routes. One major advantage of this change is that when the homepage is set to the Top route, the page title for crawlers on the homepage is now "Site name", which is a lot better.
This might be useful to revert changes made by plugins when they're disabled for example.
Bumps [zeitwerk](https://github.com/fxn/zeitwerk) from 2.7.2 to 2.7.3. - [Changelog](https://github.com/fxn/zeitwerk/blob/main/CHANGELOG.md) - [Commits](fxn/zeitwerk@v2.7.2...v2.7.3) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [rails-dom-testing](https://github.com/rails/rails-dom-testing) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/rails/rails-dom-testing/releases) - [Commits](rails/rails-dom-testing@v2.2.0...v2.3.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…l group (#33089) Bumps the babel group with 1 update: [@babel/standalone](https://github.com/babel/babel/tree/HEAD/packages/babel-standalone). Updates `@babel/standalone` from 7.27.5 to 7.27.6 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.27.6/packages/babel-standalone) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [terser](https://github.com/terser/terser) from 5.40.0 to 5.41.0. - [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md) - [Commits](terser/terser@v5.40.0...v5.41.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@swc/core](https://github.com/swc-project/swc) from 1.11.29 to 1.11.31. - [Release notes](https://github.com/swc-project/swc/releases) - [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md) - [Commits](swc-project/swc@v1.11.29...v1.11.31) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…33098) This brings the search_icon header search mode to parity with the search_field mode. We don't want to show either of these if the welcome banner is showing, since it has a search field, this is redundant. If you scroll the page and the welcome banner is hidden, then we show the header search icon. This commit also cleans up some code related to the page-search shortcut, which we no longer use, including limiting showing search on topic only if there are > 20 posts.
Bumps [rubocop-ast](https://github.com/rubocop/rubocop-ast) from 1.45.0 to 1.45.1. - [Release notes](https://github.com/rubocop/rubocop-ast/releases) - [Changelog](https://github.com/rubocop/rubocop-ast/blob/master/CHANGELOG.md) - [Commits](rubocop/rubocop-ast@v1.45.0...v1.45.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [rbtrace](https://github.com/tmm1/rbtrace) from 0.5.1 to 0.5.2. - [Changelog](https://github.com/tmm1/rbtrace/blob/master/CHANGELOG) - [Commits](https://github.com/tmm1/rbtrace/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…and work around long-url parsing issue.
Previously we would check the request for a matching CDN hostname before applying the `Access-Control-Allow-Origin` header. That logic requires the CDN to include its public-facing hostname in the `Host` header, which is not always the case. Since we are only running this `apply_cdn_headers` before_action on publicly-accessible asset routes, we can simplify things so that the `Access-Control-Allow-Origin: *` header is always included. That will make CDN config requirements much more relaxed. At the moment, this is primarily relevant to the HighlightJsController routes, which are loaded using native JS `type=module`. But in the near future, we plan to expand our use of `type=module` to more critical JS assets like translations and themes. Also drops the `Access-Control-Allow-Methods` header from these responses. That isn't needed for `GET` and `HEAD` requests.
For empty chats, a dummy message is created with `id=null` (an unsaved Ember model). The timer or placeholder's display is determined by the message ID's presence now (not the `createdAt` prop).
We will be moving towards `type="module"` for all of Discourse's JS bundles in the near future. This commit makes a start by applying the change to translation bundles.
We will be moving towards `type="module"` for all of Discourse's JS bundles in the near future. This commit makes a start by applying the change to translation bundles. This was previously merged, but the lack of `apply_cdn_headers` on the locales controller led to CORS errors on sites with CDNs.
The moment locale files expect `this.` to be the window object. In a type=module, `this` is `undefined`. This commit wraps the moment-timezone definitions in an IIFE to resolve that. Also adds a system spec to prevent future moment-timezone regressions. Followup to a2b0c19
Removing some bottom spacing + smaller font-size for mobile
Previously on iOS the chat would explicitly not scroll down to the bottom when a new message was added.
) Currently, the first two rows returned by `DiscourseDB#query_array` are silently dropped during the column size check in `DiscourseDB#load_mapping`. This happens because the rows object, while an enumerator, isn't fully compliant, it doesn't rewind during introspection. As a result, calls like `#first`, `#peek`, or `#any?` advance the iterator. Ideally, we’d fix this by updating the `query_array` enumeration implementation. However, customizing the enumerator to be fully compliant would likely introduce unnecessary perf overhead for all use cases. So, this fix works around that limitation by building the map a little differently.
This commit starts to introduce services to replace actions in the
ThemesController. We will start with the low langing fruit:
Endpoints like
#import
and#update
will be much harder.Also, the https://github.com/discourse/discourse-theme-creator plugin
overrides some of these controller actions directly, so we need
to be careful.