Project

General

Profile

Feature #44233 ยป 0001-Add-REST-API-support-for-show-update-and-destroy-on-.patch

Mizuki ISHIKAWA, 2026-07-06 08:39

View differences:

app/controllers/custom_fields_controller.rb
23 23

  
24 24
  before_action :require_admin
25 25
  before_action :build_new_custom_field, :only => [:new, :create]
26
  before_action :find_custom_field, :only => [:edit, :update, :destroy]
27
  accept_api_auth :index
26
  before_action :find_custom_field, :only => [:show, :edit, :update, :destroy]
27
  accept_api_auth :index, :show, :update, :destroy
28 28

  
29 29
  def index
30 30
    respond_to do |format|
......
44 44
    end
45 45
  end
46 46

  
47
  def show
48
    respond_to do |format|
49
      format.html {render_404}
50
      format.api
51
    end
52
  end
53

  
47 54
  def new
48 55
    @custom_field.field_format = 'string' if @custom_field.field_format.blank?
49 56
    @custom_field.default_value = nil
......
76 83
          redirect_back_or_default edit_custom_field_path(@custom_field)
77 84
        end
78 85
        format.js {head :ok}
86
        format.api {render_api_ok}
79 87
      end
80 88
    else
81 89
      respond_to do |format|
82 90
        format.html {render :action => 'edit'}
83 91
        format.js {head :unprocessable_content}
92
        format.api {render_validation_errors(@custom_field)}
84 93
      end
85 94
    end
86 95
  end
87 96

  
88 97
  def destroy
98
    error = false
89 99
    begin
90
      if @custom_field.destroy
91
        flash[:notice] = l(:notice_successful_delete)
92
      end
100
      error = true unless @custom_field.destroy
93 101
    rescue
94
      flash[:error] = l(:error_can_not_delete_custom_field)
102
      error = true
103
    end
104

  
105
    respond_to do |format|
106
      format.html do
107
        if error
108
          flash[:error] = l(:error_can_not_delete_custom_field)
109
        else
110
          flash[:notice] = l(:notice_successful_delete)
111
        end
112
        redirect_to custom_fields_path(:tab => @custom_field.class.name)
113
      end
114
      format.api do
115
        if error
116
          render_api_errors(l(:error_can_not_delete_custom_field))
117
        else
118
          render_api_ok
119
        end
120
      end
95 121
    end
96
    redirect_to custom_fields_path(:tab => @custom_field.class.name)
97 122
  end
98 123

  
99 124
  private
app/views/custom_fields/show.api.rsb
1
api.custom_field do
2
  api.id                @custom_field.id
3
  api.name              @custom_field.name
4
  api.description       @custom_field.description
5
  api.customized_type   @custom_field.class.customized_class.name.underscore if @custom_field.class.customized_class
6
  api.field_format      @custom_field.field_format
7
  api.regexp            @custom_field.regexp
8
  api.min_length        @custom_field.min_length
9
  api.max_length        @custom_field.max_length
10
  api.is_required       @custom_field.is_required?
11
  api.is_for_all        @custom_field.is_for_all?
12
  api.is_filter         @custom_field.is_filter?
13
  api.searchable        @custom_field.searchable
14
  api.multiple          @custom_field.multiple?
15
  api.default_value     @custom_field[:default_value]
16
  api.default_value_mode(@custom_field.default_value_mode.presence || 'fixed_date') if @custom_field.field_format == 'date'
17
  api.visible           @custom_field.visible?
18
  api.editable          @custom_field.editable?
19

  
20
  values = @custom_field.possible_values_options
21
  if values.present?
22
    api.array :possible_values do
23
      values.each do |label, value|
24
        api.possible_value do
25
          api.value value || label
26
          api.label label
27
        end
28
      end
29
    end
30
  end
31

  
32
  if @custom_field.is_a?(IssueCustomField)
33
    api.array :projects do
34
      @custom_field.projects.each do |project|
35
        api.project :id => project.id, :name => project.name
36
      end
37
    end
38

  
39
    api.array :trackers do
40
      @custom_field.trackers.each do |tracker|
41
        api.tracker :id => tracker.id, :name => tracker.name
42
      end
43
    end
44
  end
45

  
46
  if %w(IssueCustomField TimeEntryCustomField ProjectCustomField VersionCustomField).include?(@custom_field.class.name)
47
    api.array :roles do
48
      @custom_field.roles.each do |role|
49
        api.role :id => role.id, :name => role.name
50
      end
51
    end
52
  end
53
end
config/routes.rb
359 359
      post 'update_issue_done_ratio'
360 360
    end
361 361
  end
362
  resources :custom_fields, :except => :show do
362
  resources :custom_fields do
363 363
    resources :enumerations, :controller => 'custom_field_enumerations', :except => [:show, :new, :edit]
364 364
    put 'enumerations', :to => 'custom_field_enumerations#update_each'
365 365
  end
test/functional/custom_fields_controller_test.rb
31 31
    assert_select 'table.custom_fields'
32 32
  end
33 33

  
34
  def test_show_html_format_should_respond_with_404
35
    get :show, :params => {:id => 1}
36
    assert_response :not_found
37
  end
38

  
34 39
  def test_new_without_type_should_render_select_type
35 40
    get :new
36 41
    assert_response :success
test/integration/api_test/custom_fields_test.rb
145 145
      assert_equal '-3', element.at('default_value').text
146 146
    end
147 147
  end
148

  
149
  test "GET /custom_fields/:id.xml should return the custom field" do
150
    get '/custom_fields/1.xml', :headers => credentials('admin')
151
    assert_response :success
152
    assert_equal 'application/xml', response.media_type
153

  
154
    assert_select 'custom_field' do
155
      assert_select 'id', :text => '1'
156
      assert_select 'name', :text => 'Database'
157
      assert_select 'customized_type', :text => 'issue'
158
      assert_select 'possible_values[type=array]'
159
    end
160
  end
161

  
162
  test "GET /custom_fields/:id.json should return the custom field" do
163
    get '/custom_fields/1.json', :headers => credentials('admin')
164
    assert_response :success
165

  
166
    json = ActiveSupport::JSON.decode(response.body)
167
    assert_equal 'Database', json['custom_field']['name']
168
  end
169

  
170
  test "GET /custom_fields/:id.xml should respond with 404 for an invalid custom field" do
171
    get '/custom_fields/999.xml', :headers => credentials('admin')
172
    assert_response :not_found
173
  end
174

  
175
  test "GET /custom_fields/:id.xml should respond with 403 for a non administrator" do
176
    get '/custom_fields/1.xml', :headers => credentials('jsmith')
177
    assert_response :forbidden
178
  end
179

  
180
  test "PUT /custom_fields/:id.xml should update the custom field" do
181
    put(
182
      '/custom_fields/1.xml',
183
      :params => {:custom_field => {:name => 'Renamed'}},
184
      :headers => credentials('admin')
185
    )
186
    assert_response :no_content
187
    assert_equal 'Renamed', CustomField.find(1).name
188
  end
189

  
190
  test "PUT /custom_fields/:id.xml with invalid parameters should respond with errors" do
191
    put(
192
      '/custom_fields/1.xml',
193
      :params => {:custom_field => {:name => ''}},
194
      :headers => credentials('admin')
195
    )
196
    assert_response :unprocessable_content
197
    assert_select 'errors error', :text => "Name cannot be blank"
198
  end
199

  
200
  test "PUT /custom_fields/:id.xml should respond with 403 for a non administrator" do
201
    put(
202
      '/custom_fields/1.xml',
203
      :params => {:custom_field => {:name => 'Renamed'}},
204
      :headers => credentials('jsmith')
205
    )
206
    assert_response :forbidden
207
  end
208

  
209
  test "DELETE /custom_fields/:id.xml should destroy the custom field" do
210
    assert_difference 'CustomField.count', -1 do
211
      delete '/custom_fields/1.xml', :headers => credentials('admin')
212
    end
213
    assert_response :no_content
214
    assert_nil CustomField.find_by_id(1)
215
  end
216

  
217
  test "DELETE /custom_fields/:id.xml should respond with 403 for a non administrator" do
218
    assert_no_difference 'CustomField.count' do
219
      delete '/custom_fields/1.xml', :headers => credentials('jsmith')
220
    end
221
    assert_response :forbidden
222
  end
148 223
end
    (1-1/1)