Skip to content

Commit 3e7021d

Browse files
authored
[RFC0030 - 2] File-based service bindings app feature (#3997)
* Add presenter for file-based-service-bindings app feature * Adapt AppFeaturesController and AppFeatureUpdate * Add api docs for file-based-service-bindings app feature
1 parent 5e77dab commit 3e7021d

File tree

9 files changed

+123
-10
lines changed

9 files changed

+123
-10
lines changed

app/actions/app_feature_update.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ def self.update(feature_name, app, message)
66
app.update(enable_ssh: message.enabled)
77
when 'revisions'
88
app.update(revisions_enabled: message.enabled)
9+
when 'file-based-service-bindings'
10+
app.update(file_based_service_bindings_enabled: message.enabled)
911
end
1012
end
1113
end

app/controllers/v3/app_features_controller.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'controllers/v3/mixins/app_sub_resource'
33
require 'presenters/v3/app_ssh_feature_presenter'
44
require 'presenters/v3/app_revisions_feature_presenter'
5+
require 'presenters/v3/app_file_based_service_bindings_feature_presenter'
56
require 'presenters/v3/app_ssh_status_presenter'
67
require 'actions/app_feature_update'
78

@@ -10,8 +11,9 @@ class AppFeaturesController < ApplicationController
1011

1112
SSH_FEATURE = 'ssh'.freeze
1213
REVISIONS_FEATURE = 'revisions'.freeze
14+
FILE_BASED_SERVICE_BINDINGS_FEATURE = 'file-based-service-bindings'.freeze
1315

14-
TRUSTED_APP_FEATURES = [SSH_FEATURE].freeze
16+
TRUSTED_APP_FEATURES = [SSH_FEATURE, FILE_BASED_SERVICE_BINDINGS_FEATURE].freeze
1517
UNTRUSTED_APP_FEATURES = [REVISIONS_FEATURE].freeze
1618
APP_FEATURES = (TRUSTED_APP_FEATURES + UNTRUSTED_APP_FEATURES).freeze
1719

@@ -80,15 +82,17 @@ def present_unpagination_hash(result, path)
8082
def feature_presenter_for(feature_name, app)
8183
presenters = {
8284
SSH_FEATURE => Presenters::V3::AppSshFeaturePresenter,
83-
REVISIONS_FEATURE => Presenters::V3::AppRevisionsFeaturePresenter
85+
REVISIONS_FEATURE => Presenters::V3::AppRevisionsFeaturePresenter,
86+
FILE_BASED_SERVICE_BINDINGS_FEATURE => Presenters::V3::AppFileBasedServiceBindingsFeaturePresenter
8487
}
8588
presenters[feature_name].new(app)
8689
end
8790

8891
def presented_app_features(app)
8992
[
9093
Presenters::V3::AppSshFeaturePresenter.new(app),
91-
Presenters::V3::AppRevisionsFeaturePresenter.new(app)
94+
Presenters::V3::AppRevisionsFeaturePresenter.new(app),
95+
Presenters::V3::AppFileBasedServiceBindingsFeaturePresenter.new(app)
9296
]
9397
end
9498
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'presenters/v3/base_presenter'
2+
3+
module VCAP::CloudController::Presenters::V3
4+
class AppFileBasedServiceBindingsFeaturePresenter < BasePresenter
5+
def to_hash
6+
{
7+
name: 'file-based-service-bindings',
8+
description: 'Enable file-based service bindings for the app',
9+
enabled: app.file_based_service_bindings_enabled
10+
}
11+
end
12+
13+
private
14+
15+
def app
16+
@resource
17+
end
18+
end
19+
end

docs/v3/source/includes/api_resources/_app_features.erb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818
"name": "revisions",
1919
"description": "Enable versioning of an application",
2020
"enabled": false
21+
},
22+
{
23+
"name": "file-based-service-bindings",
24+
"description": "Enable file-based service bindings for the app",
25+
"enabled": false
2126
}
2227
],
2328
"pagination": {
24-
"total_results": 1,
29+
"total_results": 3,
2530
"total_pages": 1,
2631
"first": { "href": "/v3/apps/05d39de4-2c9e-4c76-8fd6-10417da07e42/features" },
2732
"last": { "href": "/v3/apps/05d39de4-2c9e-4c76-8fd6-10417da07e42/features" },

docs/v3/source/includes/resources/app_features/_supported_features.md.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ Name | Description
66
---- | -----------
77
**ssh** | Enable SSHing into the app
88
**revisions** | Enable [versioning](#revisions) of an application
9+
**file-based-service-bindings** | Enable file-based service bindings for the app (experimental)

spec/request/app_features_spec.rb

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let(:admin_header) { admin_headers_for(user) }
88
let(:org) { VCAP::CloudController::Organization.make(created_at: 3.days.ago) }
99
let(:space) { VCAP::CloudController::Space.make(organization: org) }
10-
let(:app_model) { VCAP::CloudController::AppModel.make(space: space, enable_ssh: true) }
10+
let(:app_model) { VCAP::CloudController::AppModel.make(space: space, enable_ssh: true, file_based_service_bindings_enabled: true) }
1111

1212
describe 'GET /v3/apps/:guid/features' do
1313
context 'getting a list of available features for the app' do
@@ -24,11 +24,16 @@
2424
'name' => 'revisions',
2525
'description' => 'Enable versioning of an application',
2626
'enabled' => true
27+
},
28+
{
29+
'name' => 'file-based-service-bindings',
30+
'description' => 'Enable file-based service bindings for the app',
31+
'enabled' => true
2732
}
2833
],
2934
'pagination' =>
3035
{
31-
'total_results' => 2,
36+
'total_results' => 3,
3237
'total_pages' => 1,
3338
'first' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
3439
'last' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
@@ -94,6 +99,19 @@
9499

95100
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
96101
end
102+
103+
context 'file-based-service-bindings app feature' do
104+
let(:api_call) { ->(user_headers) { get "/v3/apps/#{app_model.guid}/features/file-based-service-bindings", nil, user_headers } }
105+
let(:feature_response_object) do
106+
{
107+
'name' => 'file-based-service-bindings',
108+
'description' => 'Enable file-based service bindings for the app',
109+
'enabled' => true
110+
}
111+
end
112+
113+
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
114+
end
97115
end
98116

99117
describe 'PATCH /v3/apps/:guid/features/:name' do
@@ -172,5 +190,39 @@
172190
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
173191
end
174192
end
193+
194+
context 'file-based-service-bindings app feature' do
195+
let(:api_call) { ->(user_headers) { patch "/v3/apps/#{app_model.guid}/features/file-based-service-bindings", request_body.to_json, user_headers } }
196+
let(:feature_response_object) do
197+
{
198+
'name' => 'file-based-service-bindings',
199+
'description' => 'Enable file-based service bindings for the app',
200+
'enabled' => false
201+
}
202+
end
203+
204+
let(:expected_codes_and_responses) do
205+
h = Hash.new(code: 403, errors: CF_NOT_AUTHORIZED)
206+
%w[no_role org_auditor org_billing_manager].each { |r| h[r] = { code: 404 } }
207+
%w[admin space_developer].each { |r| h[r] = { code: 200, response_object: feature_response_object } }
208+
h
209+
end
210+
211+
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
212+
213+
context 'when organization is suspended' do
214+
let(:expected_codes_and_responses) do
215+
h = super()
216+
h['space_developer'] = { code: 403, errors: CF_ORG_SUSPENDED }
217+
h
218+
end
219+
220+
before do
221+
org.update(status: VCAP::CloudController::Organization::SUSPENDED)
222+
end
223+
224+
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
225+
end
226+
end
175227
end
176228
end

spec/unit/actions/app_feature_update_spec.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
module VCAP::CloudController
66
RSpec.describe AppFeatureUpdate do
77
subject(:app_feature_update) { AppFeatureUpdate }
8-
let(:app) { AppModel.make(enable_ssh: false, revisions_enabled: false) }
8+
let(:app) { AppModel.make(enable_ssh: false, revisions_enabled: false, file_based_service_bindings_enabled: false) }
99
let(:message) { AppFeatureUpdateMessage.new(enabled: true) }
1010

1111
describe '.update' do
@@ -24,6 +24,14 @@ module VCAP::CloudController
2424
end.to change { app.reload.revisions_enabled }.to(true)
2525
end
2626
end
27+
28+
context 'when the feature name is file-based-service-bindings' do
29+
it 'updates the file_based_service_bindings_enabled column on the app' do
30+
expect do
31+
AppFeatureUpdate.update('file-based-service-bindings', app, message)
32+
end.to change { app.reload.file_based_service_bindings_enabled }.to(true)
33+
end
34+
end
2735
end
2836
end
2937
end

spec/unit/controllers/v3/app_features_controller_spec.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
## NOTICE: Prefer request specs over controller specs as per ADR #0003 ##
55

66
RSpec.describe AppFeaturesController, type: :controller do
7-
let(:app_model) { VCAP::CloudController::AppModel.make(enable_ssh: true) }
7+
let(:app_model) { VCAP::CloudController::AppModel.make(enable_ssh: true, file_based_service_bindings_enabled: true) }
88
let(:space) { app_model.space }
99
let(:org) { space.organization }
1010
let(:user) { VCAP::CloudController::User.make }
1111
let(:app_feature_ssh_response) { { 'name' => 'ssh', 'description' => 'Enable SSHing into the app.', 'enabled' => true } }
1212
let(:app_feature_revisions_response) { { 'name' => 'revisions', 'description' => 'Enable versioning of an application', 'enabled' => true } }
13+
let(:app_feature_file_based_service_bindings_response) do
14+
{ 'name' => 'file-based-service-bindings', 'description' => 'Enable file-based service bindings for the app', 'enabled' => true }
15+
end
1316

1417
before do
1518
space.update(allow_ssh: true)
@@ -20,7 +23,7 @@
2023
describe '#index' do
2124
let(:pagination_hash) do
2225
{
23-
'total_results' => 2,
26+
'total_results' => 3,
2427
'total_pages' => 1,
2528
'first' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
2629
'last' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
@@ -39,7 +42,7 @@
3942
it 'returns app features' do
4043
get :index, params: { app_guid: app_model.guid }
4144
expect(parsed_body).to eq(
42-
'resources' => [app_feature_ssh_response, app_feature_revisions_response],
45+
'resources' => [app_feature_ssh_response, app_feature_revisions_response, app_feature_file_based_service_bindings_response],
4346
'pagination' => pagination_hash
4447
)
4548
end
@@ -67,6 +70,11 @@
6770
expect(parsed_body).to eq(app_feature_revisions_response)
6871
end
6972

73+
it 'returns the file-based-service-bindings app feature' do
74+
get :show, params: { app_guid: app_model.guid, name: 'file-based-service-bindings' }
75+
expect(parsed_body).to eq(app_feature_file_based_service_bindings_response)
76+
end
77+
7078
it 'throws 404 for a non-existent feature' do
7179
set_current_user_as_role(role: 'admin', org: org, space: space, user: user)
7280

spec/unit/presenters/v3/app_feature_presenter_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'spec_helper'
22
require 'presenters/v3/app_ssh_feature_presenter'
3+
require 'presenters/v3/app_file_based_service_bindings_feature_presenter'
34

45
module VCAP::CloudController::Presenters::V3
56
RSpec.describe AppSshFeaturePresenter do
@@ -14,4 +15,17 @@ module VCAP::CloudController::Presenters::V3
1415
end
1516
end
1617
end
18+
19+
RSpec.describe AppFileBasedServiceBindingsFeaturePresenter do
20+
let(:app) { VCAP::CloudController::AppModel.make }
21+
22+
describe '#to_hash' do
23+
it 'presents the app feature as json' do
24+
result = AppFileBasedServiceBindingsFeaturePresenter.new(app).to_hash
25+
expect(result[:name]).to eq('file-based-service-bindings')
26+
expect(result[:description]).to eq('Enable file-based service bindings for the app')
27+
expect(result[:enabled]).to eq(app.file_based_service_bindings_enabled)
28+
end
29+
end
30+
end
1731
end

0 commit comments

Comments
 (0)