Skip to content
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

[RFC0030 - 2] File-based service bindings app feature #3997

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/actions/app_feature_update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ def self.update(feature_name, app, message)
app.update(enable_ssh: message.enabled)
when 'revisions'
app.update(revisions_enabled: message.enabled)
when 'file-based-service-bindings'
app.update(file_based_service_bindings_enabled: message.enabled)
end
end
end
Expand Down
10 changes: 7 additions & 3 deletions app/controllers/v3/app_features_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'controllers/v3/mixins/app_sub_resource'
require 'presenters/v3/app_ssh_feature_presenter'
require 'presenters/v3/app_revisions_feature_presenter'
require 'presenters/v3/app_file_based_service_bindings_feature_presenter'
require 'presenters/v3/app_ssh_status_presenter'
require 'actions/app_feature_update'

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

SSH_FEATURE = 'ssh'.freeze
REVISIONS_FEATURE = 'revisions'.freeze
FILE_BASED_SERVICE_BINDINGS_FEATURE = 'file-based-service-bindings'.freeze

TRUSTED_APP_FEATURES = [SSH_FEATURE].freeze
TRUSTED_APP_FEATURES = [SSH_FEATURE, FILE_BASED_SERVICE_BINDINGS_FEATURE].freeze
UNTRUSTED_APP_FEATURES = [REVISIONS_FEATURE].freeze
APP_FEATURES = (TRUSTED_APP_FEATURES + UNTRUSTED_APP_FEATURES).freeze

Expand Down Expand Up @@ -80,15 +82,17 @@ def present_unpagination_hash(result, path)
def feature_presenter_for(feature_name, app)
presenters = {
SSH_FEATURE => Presenters::V3::AppSshFeaturePresenter,
REVISIONS_FEATURE => Presenters::V3::AppRevisionsFeaturePresenter
REVISIONS_FEATURE => Presenters::V3::AppRevisionsFeaturePresenter,
FILE_BASED_SERVICE_BINDINGS_FEATURE => Presenters::V3::AppFileBasedServiceBindingsFeaturePresenter
}
presenters[feature_name].new(app)
end

def presented_app_features(app)
[
Presenters::V3::AppSshFeaturePresenter.new(app),
Presenters::V3::AppRevisionsFeaturePresenter.new(app)
Presenters::V3::AppRevisionsFeaturePresenter.new(app),
Presenters::V3::AppFileBasedServiceBindingsFeaturePresenter.new(app)
]
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'presenters/v3/base_presenter'

module VCAP::CloudController::Presenters::V3
class AppFileBasedServiceBindingsFeaturePresenter < BasePresenter
def to_hash
{
name: 'file-based-service-bindings',
description: 'Enable file-based service bindings for the app',
enabled: app.file_based_service_bindings_enabled
}
end

private

def app
@resource
end
end
end
7 changes: 6 additions & 1 deletion docs/v3/source/includes/api_resources/_app_features.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@
"name": "revisions",
"description": "Enable versioning of an application",
"enabled": false
},
{
"name": "file-based-service-bindings",
"description": "Enable file-based service bindings for the app",
"enabled": false
}
],
"pagination": {
"total_results": 1,
"total_results": 3,
"total_pages": 1,
"first": { "href": "/v3/apps/05d39de4-2c9e-4c76-8fd6-10417da07e42/features" },
"last": { "href": "/v3/apps/05d39de4-2c9e-4c76-8fd6-10417da07e42/features" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ Name | Description
---- | -----------
**ssh** | Enable SSHing into the app
**revisions** | Enable [versioning](#revisions) of an application
**file-based-service-bindings** | Enable file-based service bindings for the app (experimental)
56 changes: 54 additions & 2 deletions spec/request/app_features_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:admin_header) { admin_headers_for(user) }
let(:org) { VCAP::CloudController::Organization.make(created_at: 3.days.ago) }
let(:space) { VCAP::CloudController::Space.make(organization: org) }
let(:app_model) { VCAP::CloudController::AppModel.make(space: space, enable_ssh: true) }
let(:app_model) { VCAP::CloudController::AppModel.make(space: space, enable_ssh: true, file_based_service_bindings_enabled: true) }

describe 'GET /v3/apps/:guid/features' do
context 'getting a list of available features for the app' do
Expand All @@ -24,11 +24,16 @@
'name' => 'revisions',
'description' => 'Enable versioning of an application',
'enabled' => true
},
{
'name' => 'file-based-service-bindings',
'description' => 'Enable file-based service bindings for the app',
'enabled' => true
}
],
'pagination' =>
{
'total_results' => 2,
'total_results' => 3,
'total_pages' => 1,
'first' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
'last' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
Expand Down Expand Up @@ -94,6 +99,19 @@

it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
end

context 'file-based-service-bindings app feature' do
let(:api_call) { ->(user_headers) { get "/v3/apps/#{app_model.guid}/features/file-based-service-bindings", nil, user_headers } }
let(:feature_response_object) do
{
'name' => 'file-based-service-bindings',
'description' => 'Enable file-based service bindings for the app',
'enabled' => true
}
end

it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
end
end

describe 'PATCH /v3/apps/:guid/features/:name' do
Expand Down Expand Up @@ -172,5 +190,39 @@
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
end
end

context 'file-based-service-bindings app feature' do
let(:api_call) { ->(user_headers) { patch "/v3/apps/#{app_model.guid}/features/file-based-service-bindings", request_body.to_json, user_headers } }
let(:feature_response_object) do
{
'name' => 'file-based-service-bindings',
'description' => 'Enable file-based service bindings for the app',
'enabled' => false
}
end

let(:expected_codes_and_responses) do
h = Hash.new(code: 403, errors: CF_NOT_AUTHORIZED)
%w[no_role org_auditor org_billing_manager].each { |r| h[r] = { code: 404 } }
%w[admin space_developer].each { |r| h[r] = { code: 200, response_object: feature_response_object } }
h
end

it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS

context 'when organization is suspended' do
let(:expected_codes_and_responses) do
h = super()
h['space_developer'] = { code: 403, errors: CF_ORG_SUSPENDED }
h
end

before do
org.update(status: VCAP::CloudController::Organization::SUSPENDED)
end

it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
end
end
end
end
10 changes: 9 additions & 1 deletion spec/unit/actions/app_feature_update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
module VCAP::CloudController
RSpec.describe AppFeatureUpdate do
subject(:app_feature_update) { AppFeatureUpdate }
let(:app) { AppModel.make(enable_ssh: false, revisions_enabled: false) }
let(:app) { AppModel.make(enable_ssh: false, revisions_enabled: false, file_based_service_bindings_enabled: false) }
let(:message) { AppFeatureUpdateMessage.new(enabled: true) }

describe '.update' do
Expand All @@ -24,6 +24,14 @@ module VCAP::CloudController
end.to change { app.reload.revisions_enabled }.to(true)
end
end

context 'when the feature name is file-based-service-bindings' do
it 'updates the file_based_service_bindings_enabled column on the app' do
expect do
AppFeatureUpdate.update('file-based-service-bindings', app, message)
end.to change { app.reload.file_based_service_bindings_enabled }.to(true)
end
end
end
end
end
14 changes: 11 additions & 3 deletions spec/unit/controllers/v3/app_features_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
## NOTICE: Prefer request specs over controller specs as per ADR #0003 ##

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

before do
space.update(allow_ssh: true)
Expand All @@ -20,7 +23,7 @@
describe '#index' do
let(:pagination_hash) do
{
'total_results' => 2,
'total_results' => 3,
'total_pages' => 1,
'first' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
'last' => { 'href' => "/v3/apps/#{app_model.guid}/features" },
Expand All @@ -39,7 +42,7 @@
it 'returns app features' do
get :index, params: { app_guid: app_model.guid }
expect(parsed_body).to eq(
'resources' => [app_feature_ssh_response, app_feature_revisions_response],
'resources' => [app_feature_ssh_response, app_feature_revisions_response, app_feature_file_based_service_bindings_response],
'pagination' => pagination_hash
)
end
Expand Down Expand Up @@ -67,6 +70,11 @@
expect(parsed_body).to eq(app_feature_revisions_response)
end

it 'returns the file-based-service-bindings app feature' do
get :show, params: { app_guid: app_model.guid, name: 'file-based-service-bindings' }
expect(parsed_body).to eq(app_feature_file_based_service_bindings_response)
end

it 'throws 404 for a non-existent feature' do
set_current_user_as_role(role: 'admin', org: org, space: space, user: user)

Expand Down
14 changes: 14 additions & 0 deletions spec/unit/presenters/v3/app_feature_presenter_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'spec_helper'
require 'presenters/v3/app_ssh_feature_presenter'
require 'presenters/v3/app_file_based_service_bindings_feature_presenter'

module VCAP::CloudController::Presenters::V3
RSpec.describe AppSshFeaturePresenter do
Expand All @@ -14,4 +15,17 @@ module VCAP::CloudController::Presenters::V3
end
end
end

RSpec.describe AppFileBasedServiceBindingsFeaturePresenter do
let(:app) { VCAP::CloudController::AppModel.make }

describe '#to_hash' do
it 'presents the app feature as json' do
result = AppFileBasedServiceBindingsFeaturePresenter.new(app).to_hash
expect(result[:name]).to eq('file-based-service-bindings')
expect(result[:description]).to eq('Enable file-based service bindings for the app')
expect(result[:enabled]).to eq(app.file_based_service_bindings_enabled)
end
end
end
end
Loading