diff --git a/app/components/oauth/applications/application_row_component.html.erb b/app/components/oauth/applications/application_row_component.html.erb new file mode 100644 index 000000000000..5813d4cd4aab --- /dev/null +++ b/app/components/oauth/applications/application_row_component.html.erb @@ -0,0 +1,40 @@ +<%= + component_wrapper do + flex_layout(align_items: :center, justify_content: :space_between) do |oauth_application_container| + oauth_application_container.with_column(flex_layout: true) do |application_information| + application_information.with_column(mr: 2) do + render(Primer::Beta::Link.new(href: oauth_application_path(@application), font_weight: :bold)) do + @application.name + end + end + + application_information.with_column(mr: 2) do + render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) do + if @application.builtin? + t("oauth.application.builtin") + else + t(:label_created_by, user: @application.owner) + end + end + end + + unless @application.builtin? + application_information.with_column do + render(Primer::Beta::Label.new) do + @application.confidential? ? t("oauth.application.confidential") : t("oauth.application.non_confidential") + end + end + end + end + + # Actions + oauth_application_container.with_column do + render(Primer::Alpha::ToggleSwitch.new( + src: toggle_oauth_application_path(@application), + csrf_token: form_authenticity_token, + checked: @application.enabled? + )) + end + end + end +%> diff --git a/app/components/oauth/applications/application_row_component.rb b/app/components/oauth/applications/application_row_component.rb new file mode 100644 index 000000000000..8ee4387de717 --- /dev/null +++ b/app/components/oauth/applications/application_row_component.rb @@ -0,0 +1,43 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module OAuth + module Applications + class ApplicationRowComponent < ApplicationComponent + include ApplicationHelper + include OpPrimer::ComponentHelpers + include OpTurbo::Streamable + + def initialize(application:) + @application = application + + super + end + end + end +end diff --git a/app/components/oauth/applications/index_component.html.erb b/app/components/oauth/applications/index_component.html.erb new file mode 100644 index 000000000000..020862cae064 --- /dev/null +++ b/app/components/oauth/applications/index_component.html.erb @@ -0,0 +1,49 @@ +<%= + component_wrapper do + flex_layout do |index_container| + index_container.with_row do + render(border_box_container(mb: 4)) do |component| + component.with_header(font_weight: :bold) do + render(Primer::Beta::Text.new) do + t("oauth.header.builtin_applications") + end + end + + if @built_in_applications.empty? + component.with_row do + render(Primer::Beta::Text.new) do + t("oauth.empty_application_lists") + end + end + end + + @built_in_applications.each do |application| + component.with_row { render(OAuth::Applications::ApplicationRowComponent.new(application:)) } + end + end + end + + index_container.with_row do + render(border_box_container(mb: 4)) do |component| + component.with_header(font_weight: :bold) do + render(Primer::Beta::Text.new) do + t("oauth.header.other_applications") + end + end + + if @other_applications.empty? + component.with_row do + render(Primer::Beta::Text.new) do + t("oauth.empty_application_lists") + end + end + end + + @other_applications.each do |application| + component.with_row { render(OAuth::Applications::ApplicationRowComponent.new(application:)) } + end + end + end + end + end +%> diff --git a/app/components/oauth/applications/index_component.rb b/app/components/oauth/applications/index_component.rb new file mode 100644 index 000000000000..81027eea51f3 --- /dev/null +++ b/app/components/oauth/applications/index_component.rb @@ -0,0 +1,44 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module OAuth + module Applications + class IndexComponent < ApplicationComponent + include ApplicationHelper + include OpPrimer::ComponentHelpers + include OpTurbo::Streamable + + def initialize(oauth_applications:) + @built_in_applications = oauth_applications.select(&:builtin?) + @other_applications = oauth_applications.reject(&:builtin?) + + super + end + end + end +end diff --git a/app/components/oauth/applications/row_component.rb b/app/components/oauth/applications/row_component.rb deleted file mode 100644 index 2778023eca9f..000000000000 --- a/app/components/oauth/applications/row_component.rb +++ /dev/null @@ -1,114 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -module OAuth - module Applications - class RowComponent < ::RowComponent - property :confidential - - def application - model - end - - def builtin - checkmark(application.builtin?) - end - - def enabled - checkmark(application.enabled?) - end - - def name - if enabled - link_to application.name, oauth_application_path(application) - else - render(Primer::Beta::Text.new(color: :muted)) { application.name } - end - end - - def owner - link_to application.owner.name, user_path(application.owner) - end - - def confidential - if application.confidential? - helpers.op_icon "icon icon-checkmark" - end - end - - def redirect_uri - urls = application.redirect_uri.split("\n") - safe_join urls, "
".html_safe - end - - def client_credentials - if user_id = application.client_credentials_user_id - helpers.link_to_user User.find(user_id) - else - "-" - end - end - - def edit_link - link_to( - I18n.t(:button_edit), - edit_oauth_application_path(application), - class: "oauth-application--edit-link icon icon-edit" - ) - end - - def button_links - if application.builtin? - [toggle_enabled_link] - else - [edit_link, helpers.delete_link(oauth_application_path(application))] - end - end - - def toggle_enabled_link - if application.enabled? - link_to( - I18n.t(:button_deactivate), - toggle_oauth_application_path(application), - class: "oauth-application--edit-link icon icon-lock", - method: :post - ) - else - link_to( - I18n.t(:button_activate), - toggle_oauth_application_path(application), - class: "oauth-application--edit-link icon icon-unlock", - method: :post - ) - end - end - end - end -end diff --git a/app/components/oauth/applications/table_component.rb b/app/components/oauth/applications/table_component.rb deleted file mode 100644 index 85ef1ef6175a..000000000000 --- a/app/components/oauth/applications/table_component.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -module OAuth - module Applications - class TableComponent < ::TableComponent - class << self - def row_class - ::OAuth::Applications::RowComponent - end - end - - def initial_sort - %i[id asc] - end - - def sortable? - false - end - - def columns - headers.map(&:first) - end - - def inline_create_link - link_to new_oauth_application_path, - aria: { label: t("oauth.application.new") }, - class: "wp-inline-create--add-link", - title: t("oauth.application.new") do - helpers.op_icon("icon icon-add") - end - end - - def empty_row_message - I18n.t :no_results_title_text - end - - def headers - [ - ["name", { caption: ::Doorkeeper::Application.human_attribute_name(:name) }], - ["owner", { caption: ::Doorkeeper::Application.human_attribute_name(:owner) }], - ["builtin", { caption: ::Doorkeeper::Application.human_attribute_name(:builtin) }], - ["enabled", { caption: ::Doorkeeper::Application.human_attribute_name(:enabled) }], - ["client_credentials", { caption: I18n.t("oauth.client_credentials") }], - ["redirect_uri", { caption: ::Doorkeeper::Application.human_attribute_name(:redirect_uri) }], - ["confidential", { caption: ::Doorkeeper::Application.human_attribute_name(:confidential) }] - ] - end - end - end -end diff --git a/app/components/oauth/show_page_header_component.html.erb b/app/components/oauth/show_page_header_component.html.erb index d340f870abcb..8bb3d06627e8 100644 --- a/app/components/oauth/show_page_header_component.html.erb +++ b/app/components/oauth/show_page_header_component.html.erb @@ -32,31 +32,33 @@ See COPYRIGHT and LICENSE files for more details. header.with_title { h(@application.name) } header.with_breadcrumbs(breadcrumb_items) - header.with_action_button(tag: :a, - mobile_icon: :pencil, - mobile_label: t(:button_edit), - size: :medium, - href: edit_oauth_application_path(@application), - aria: { label: I18n.t(:button_edit) }, - title: I18n.t(:button_edit)) do |button| - button.with_leading_visual_icon(icon: :pencil) - t(:button_edit) - end + unless @application.builtin? + header.with_action_button(tag: :a, + mobile_icon: :pencil, + mobile_label: t(:button_edit), + size: :medium, + href: edit_oauth_application_path(@application), + aria: { label: I18n.t(:button_edit) }, + title: I18n.t(:button_edit)) do |button| + button.with_leading_visual_icon(icon: :pencil) + t(:button_edit) + end - header.with_action_button(tag: :a, - scheme: :danger, - mobile_icon: :trash, - mobile_label: t(:button_delete), - size: :medium, - href: oauth_application_path(@application), - aria: { label: I18n.t(:button_delete) }, - data: { - confirm: I18n.t(:text_are_you_sure), - method: :delete - }, - title: I18n.t(:button_delete)) do |button| - button.with_leading_visual_icon(icon: :trash) - t(:button_delete) + header.with_action_button(tag: :a, + scheme: :danger, + mobile_icon: :trash, + mobile_label: t(:button_delete), + size: :medium, + href: oauth_application_path(@application), + aria: { label: I18n.t(:button_delete) }, + data: { + confirm: I18n.t(:text_are_you_sure), + method: :delete + }, + title: I18n.t(:button_delete)) do |button| + button.with_leading_visual_icon(icon: :trash) + t(:button_delete) + end end end %> diff --git a/app/contracts/oauth/applications/base_contract.rb b/app/contracts/oauth/applications/base_contract.rb index 4016cfffb51c..fac8b49b1873 100644 --- a/app/contracts/oauth/applications/base_contract.rb +++ b/app/contracts/oauth/applications/base_contract.rb @@ -51,16 +51,14 @@ def self.model private def validate_admin_only - unless user.active_admin? - errors.add :base, :error_unauthorized - end + errors.add :base, :error_unauthorized unless user.admin? end def validate_integration - if (model.integration_id.nil? && model.integration_type.present?) || - (model.integration_id.present? && model.integration_type.nil?) - errors.add :integration, :invalid - end + both = model.integration_id.present? && model.integration_type.present? + none = model.integration_id.nil? && model.integration_type.nil? + + errors.add :integration, :invalid unless both || none end def validate_client_credential_user diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb index 113c86ae3f8c..0d32225d584b 100644 --- a/app/controllers/oauth/applications_controller.rb +++ b/app/controllers/oauth/applications_controller.rb @@ -53,13 +53,14 @@ def edit; end def create call = ::OAuth::Applications::CreateService.new(user: current_user) .call(permitted_params.oauth_application) + result = call.result if call.success? flash[:notice] = t(:notice_successful_create) - flash[:_application_secret] = call.result.plaintext_secret - redirect_to action: :show, id: call.result.id + flash[:_application_secret] = result.plaintext_secret + redirect_to action: :show, id: result.id else - @application = call.result + @application = result render action: :new end end diff --git a/app/models/user.rb b/app/models/user.rb index ef48d89c298d..23e85c02b3bf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -413,10 +413,6 @@ def wants_comments_in_reverse_order? pref.comments_in_reverse_order? end - def active_admin? - admin? && active? - end - def self.find_by_rss_key(key) return nil unless Setting.feeds_enabled? diff --git a/app/seeders/oauth_applications_seeder.rb b/app/seeders/oauth_applications_seeder.rb index aee146695513..b8f88606db18 100644 --- a/app/seeders/oauth_applications_seeder.rb +++ b/app/seeders/oauth_applications_seeder.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) 2012-2024 the OpenProject GmbH @@ -26,6 +28,8 @@ # See COPYRIGHT and LICENSE files for more details. #++ class OAuthApplicationsSeeder < Seeder + OPENPROJECT_MOBILE_APP_UID = "DgJZ7Rat23xHZbcq_nxPg5RUuxljonLCN7V7N7GoBAA" + def seed_data! call = create_app unless call.success? @@ -37,11 +41,11 @@ def seed_data! end def applicable? - Doorkeeper::Application.where(builtin: true).empty? + Doorkeeper::Application.find_by(id: OPENPROJECT_MOBILE_APP_UID).nil? end def not_applicable_message - "No need to seed oauth appplications as they are already present." + "No need to seed oauth applications as they are already present." end def create_app @@ -53,7 +57,7 @@ def create_app redirect_uri: "openprojectapp://oauth-callback", builtin: true, confidential: false, - uid: "DgJZ7Rat23xHZbcq_nxPg5RUuxljonLCN7V7N7GoBAA" + uid: OPENPROJECT_MOBILE_APP_UID ) end end diff --git a/app/views/oauth/applications/index.html.erb b/app/views/oauth/applications/index.html.erb index 3f290aa417bf..c9dc6f66d2ae 100644 --- a/app/views/oauth/applications/index.html.erb +++ b/app/views/oauth/applications/index.html.erb @@ -24,8 +24,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. - ++#%> + <% html_title t(:label_administration), t("oauth.application.plural") -%> <%= @@ -50,4 +50,4 @@ See COPYRIGHT and LICENSE files for more details. end %> -<%= render ::OAuth::Applications::TableComponent.new(rows: @applications) %> +<%= render ::OAuth::Applications::IndexComponent.new(oauth_applications: @applications) %> diff --git a/app/views/oauth/applications/show.html.erb b/app/views/oauth/applications/show.html.erb index bcd963c864e3..c2f07ed2595d 100644 --- a/app/views/oauth/applications/show.html.erb +++ b/app/views/oauth/applications/show.html.erb @@ -31,28 +31,6 @@ See COPYRIGHT and LICENSE files for more details. <%= render OAuth::ShowPageHeaderComponent.new(application: @application) %> -<%= toolbar title: "#{t('oauth.application.singular')} - #{h(@application.name)}", - title_class: 'no-padding-bottom' do %> - <% unless @application.builtin? %> -
  • - <%= link_to edit_oauth_application_path(@application), - class: 'button' do %> - <%= op_icon('button--icon icon-edit') %> - <%= t(:button_edit) %> - <% end %> -
  • -
  • - <%= link_to oauth_application_path(@application), - method: :delete, - data: { confirm: I18n.t(:text_are_you_sure) }, - class: 'button -danger' do %> - <%= op_icon('button--icon icon-delete') %> - <%= t(:button_delete) %> - <% end %> -
  • - <% end %> -<% end %> - <%= render(AttributeGroups::AttributeGroupComponent.new) do |component| %> <% component.with_header(title: t(:label_details)) %> @@ -93,6 +71,11 @@ See COPYRIGHT and LICENSE files for more details. value: @application.confidential? ? t(:general_text_Yes) : t(:general_text_No) ) %> + <% component.with_attribute( + key: @application.class.human_attribute_name(:enabled), + value: @application.enabled? ? t(:general_text_Yes) : t(:general_text_No) + ) %> + <% component.with_attribute( key: @application.class.human_attribute_name(:redirect_uri), value: safe_join(@application.redirect_uri.split("\n"), tag(:br)) diff --git a/config/locales/en.yml b/config/locales/en.yml index fed2c349fbb2..81187cf64518 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1404,7 +1404,6 @@ en: limit_reached: You can only do %{limit} backups per day. button_actions: "Actions" - button_activate: "Activate" button_add: "Add" button_add_comment: "Add comment" button_add_member: Add member @@ -1430,7 +1429,6 @@ en: button_copy_and_follow: "Copy and follow" button_create: "Create" button_create_and_continue: "Create and continue" - button_deactivate: "Deactivate" button_delete: "Delete" button_decline: "Decline" button_delete_watcher: "Delete watcher %{name}" @@ -2147,6 +2145,7 @@ en: label_copy_project: "Copy project" label_core_version: "Core version" label_core_build: "Core build" + label_created_by: "Created by %{user}" label_current_status: "Current status" label_current_version: "Current version" label_custom_field_add_no_type: "Add this field to a work package type" @@ -3994,10 +3993,13 @@ en: oauth: application: + builtin: Built-in instance application + confidential: Confidential singular: "OAuth application" plural: "OAuth applications" named: "OAuth application '%{name}'" new: "New OAuth application" + non_confidential: Non confidential default_scopes: "(Default scopes)" instructions: enabled: "Enable this application, allowing users to perform authorization grants with it." @@ -4011,6 +4013,10 @@ en: client_credential_user_id: "Optional user ID to impersonate when clients use this application. Leave empty to allow public access only" register_intro: "If you are developing an OAuth API client application for OpenProject, you can register it using this form for all users to use." default_scopes: "" + header: + builtin_applications: Built-in OAuth applications + other_applications: Other OAuth applications + empty_application_lists: No OAuth applications have been registered. client_id: "Client ID" client_secret_notice: > This is the only time we can print the client secret, please note it down and keep it secure. diff --git a/db/migrate/20240513135928_extend_oauth_applications.rb b/db/migrate/20240513135928_extend_oauth_applications.rb index 1c531cc451cc..18ec11c1fe37 100644 --- a/db/migrate/20240513135928_extend_oauth_applications.rb +++ b/db/migrate/20240513135928_extend_oauth_applications.rb @@ -1,6 +1,8 @@ class ExtendOAuthApplications < ActiveRecord::Migration[7.1] def change - add_column :oauth_applications, :builtin, :boolean, default: false - add_column :oauth_applications, :enabled, :boolean, default: true + change_table :oauth_applications, bulk: true do |t| + t.column :enabled, :boolean, default: true, null: false + t.column :builtin, :boolean, default: false, null: false + end end end diff --git a/spec/features/admin/oauth/oauth_applications_management_spec.rb b/spec/features/admin/oauth/oauth_applications_management_spec.rb index 3c69acb22dad..149c750943cc 100644 --- a/spec/features/admin/oauth/oauth_applications_management_spec.rb +++ b/spec/features/admin/oauth/oauth_applications_management_spec.rb @@ -95,7 +95,7 @@ context "with a seeded application" do before do - ::OAuthApplicationsSeeder.new.seed_data! + OAuthApplicationsSeeder.new.seed_data! end it "does not allow editing or deleting the seeded application" do @@ -105,14 +105,14 @@ expect(page).to have_css("td.builtin .icon-checkmark") expect(page).to have_css("td.enabled .icon-checkmark") - expect(page).not_to have_css("td.buttons", text: "Edit") - expect(page).not_to have_css("td.buttons", text: "Delete") + expect(page).to have_no_css("td.buttons", text: "Edit") + expect(page).to have_no_css("td.buttons", text: "Delete") expect(page).to have_css("td.buttons", text: "Deactivate") click_link_or_button "Deactivate" expect(page).to have_css("td.builtin .icon-checkmark") - expect(page).not_to have_css("td.enabled .icon-checkmark") + expect(page).to have_no_css("td.enabled .icon-checkmark") app = Doorkeeper::Application.last expect(app).to be_builtin diff --git a/spec/services/oauth/applications/create_service_spec.rb b/spec/services/oauth/applications/create_service_spec.rb index 962113a3e908..bc299a08502e 100644 --- a/spec/services/oauth/applications/create_service_spec.rb +++ b/spec/services/oauth/applications/create_service_spec.rb @@ -31,9 +31,9 @@ require "spec_helper" require "services/base_services/behaves_like_create_service" -RSpec.describe OAuth::Applications::CreateService, type: :model do +RSpec.describe OAuth::Applications::CreateService, type: :model do # rubocop:disable RSpec/SpecFilePathFormat it_behaves_like "BaseServices create service" do - let(:factory) { :oauth_application } let(:model_class) { Doorkeeper::Application } + let(:factory) { :oauth_application } end end diff --git a/spec/services/oauth/applications/delete_service_spec.rb b/spec/services/oauth/applications/delete_service_spec.rb index dc0d151771e6..4fcb9b55fcf0 100644 --- a/spec/services/oauth/applications/delete_service_spec.rb +++ b/spec/services/oauth/applications/delete_service_spec.rb @@ -31,7 +31,7 @@ require "spec_helper" require "services/base_services/behaves_like_delete_service" -RSpec.describe OAuth::Applications::DeleteService, type: :model do +RSpec.describe OAuth::Applications::DeleteService, type: :model do # rubocop:disable RSpec/SpecFilePathFormat it_behaves_like "BaseServices delete service" do let(:factory) { :oauth_application } end diff --git a/spec/services/oauth/applications/set_attributes_service_spec.rb b/spec/services/oauth/applications/set_attributes_service_spec.rb index 5b891f89fc8b..396522209ceb 100644 --- a/spec/services/oauth/applications/set_attributes_service_spec.rb +++ b/spec/services/oauth/applications/set_attributes_service_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe OAuth::Applications::SetAttributesService, type: :model do +RSpec.describe OAuth::Applications::SetAttributesService, type: :model do # rubocop:disable RSpec/SpecFilePathFormat let(:current_user) { build_stubbed(:admin) } let(:contract_instance) do diff --git a/spec/services/oauth/applications/update_service_spec.rb b/spec/services/oauth/applications/update_service_spec.rb index eceb08d8a643..a8523eb94f1e 100644 --- a/spec/services/oauth/applications/update_service_spec.rb +++ b/spec/services/oauth/applications/update_service_spec.rb @@ -31,7 +31,7 @@ require "spec_helper" require "services/base_services/behaves_like_update_service" -RSpec.describe OAuth::Applications::UpdateService, type: :model do +RSpec.describe OAuth::Applications::UpdateService, type: :model do # rubocop:disable RSpec/SpecFilePathFormat it_behaves_like "BaseServices update service" do let(:factory) { :oauth_application } end