mno-enterprise-api 3.1.4 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/mno_enterprise/config.js.coffee.erb +7 -1
- data/app/controllers/mno_enterprise/auth/omniauth_callbacks_controller.rb +3 -27
- data/app/controllers/mno_enterprise/auth/sessions_controller.rb +1 -3
- data/app/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller.rb +26 -0
- data/app/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller.rb +28 -0
- data/app/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller.rb +16 -0
- data/app/controllers/mno_enterprise/jpi/v1/admin/app_reviews_controller.rb +30 -0
- data/app/controllers/mno_enterprise/jpi/v1/admin/invites_controller.rb +1 -1
- data/app/controllers/mno_enterprise/jpi/v1/admin/organizations_controller.rb +55 -37
- data/app/controllers/mno_enterprise/jpi/v1/app_answers_controller.rb +22 -0
- data/app/controllers/mno_enterprise/jpi/v1/app_comments_controller.rb +22 -0
- data/app/controllers/mno_enterprise/jpi/v1/app_feedbacks_controller.rb +14 -0
- data/app/controllers/mno_enterprise/jpi/v1/app_instances_controller.rb +1 -20
- data/app/controllers/mno_enterprise/jpi/v1/app_questions_controller.rb +25 -0
- data/app/controllers/mno_enterprise/jpi/v1/app_reviews_controller.rb +94 -0
- data/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb +12 -0
- data/app/controllers/mno_enterprise/jpi/v1/impac/alerts_controller.rb +5 -0
- data/app/controllers/mno_enterprise/jpi/v1/impac/kpis_controller.rb +1 -76
- data/app/controllers/mno_enterprise/jpi/v1/marketplace_controller.rb +1 -18
- data/app/controllers/mno_enterprise/jpi/v1/teams_controller.rb +1 -83
- data/app/jobs/mno_enterprise/event_logger_job.rb +10 -0
- data/app/views/mno_enterprise/auth/confirmations/new.html.haml +6 -6
- data/app/views/mno_enterprise/auth/passwords/new.html.haml +8 -8
- data/app/views/mno_enterprise/auth/registrations/new.html.haml +1 -0
- data/app/views/mno_enterprise/auth/sessions/new.html.haml +1 -0
- data/app/views/mno_enterprise/auth/shared/_links.html.haml +0 -5
- data/app/views/mno_enterprise/auth/shared/_omniauth.html.haml +10 -0
- data/app/views/mno_enterprise/jpi/v1/admin/app_answers/show.json.jbuilder +15 -0
- data/app/views/mno_enterprise/jpi/v1/admin/app_comments/show.json.jbuilder +15 -0
- data/app/views/mno_enterprise/jpi/v1/admin/app_reviews/_app_review.json.jbuilder +13 -0
- data/app/views/mno_enterprise/jpi/v1/admin/app_reviews/index.json.jbuilder +1 -0
- data/app/views/mno_enterprise/jpi/v1/admin/app_reviews/show.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/admin/organizations/show.json.jbuilder +1 -0
- data/app/views/mno_enterprise/jpi/v1/admin/users/_user.json.jbuilder +1 -1
- data/app/views/mno_enterprise/jpi/v1/app_answers/_resource.json.jbuilder +4 -0
- data/app/views/mno_enterprise/jpi/v1/app_answers/index.json.jbuilder +5 -0
- data/app/views/mno_enterprise/jpi/v1/app_answers/show.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/app_comments/_resource.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/app_comments/index.json.jbuilder +5 -0
- data/app/views/mno_enterprise/jpi/v1/app_comments/show.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/app_feedbacks/_comment.json.jbuilder +10 -0
- data/app/views/mno_enterprise/jpi/v1/app_feedbacks/_resource.json.jbuilder +7 -0
- data/app/views/mno_enterprise/jpi/v1/app_feedbacks/index.json.jbuilder +5 -0
- data/app/views/mno_enterprise/jpi/v1/app_feedbacks/show.json.jbuilder +4 -0
- data/app/views/mno_enterprise/jpi/v1/app_instances/_resource.json.jbuilder +9 -0
- data/app/views/mno_enterprise/jpi/v1/app_questions/_answer.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/app_questions/_resource.json.jbuilder +8 -0
- data/app/views/mno_enterprise/jpi/v1/app_questions/index.json.jbuilder +5 -0
- data/app/views/mno_enterprise/jpi/v1/app_questions/show.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/app_reviews/_resource.json.jbuilder +13 -0
- data/app/views/mno_enterprise/jpi/v1/app_reviews/index.json.jbuilder +5 -0
- data/app/views/mno_enterprise/jpi/v1/app_reviews/show.json.jbuilder +4 -0
- data/app/views/mno_enterprise/jpi/v1/base_resource/_app_review.json.jbuilder +17 -0
- data/app/views/mno_enterprise/jpi/v1/current_users/show.json.jbuilder +9 -1
- data/app/views/mno_enterprise/jpi/v1/impac/alerts/_alert.json.jbuilder +7 -0
- data/app/views/mno_enterprise/jpi/v1/impac/alerts/index.json.jbuilder +1 -0
- data/app/views/mno_enterprise/jpi/v1/impac/alerts/show.json.jbuilder +1 -0
- data/app/views/mno_enterprise/jpi/v1/impac/dashboards/_dashboard.json.jbuilder +8 -3
- data/app/views/mno_enterprise/jpi/v1/impac/kpis/_kpi.json.jbuilder +4 -1
- data/app/views/mno_enterprise/jpi/v1/impac/widgets/_widget.json.jbuilder +1 -1
- data/app/views/mno_enterprise/jpi/v1/impac/widgets/index.json.jbuilder +3 -0
- data/app/views/mno_enterprise/jpi/v1/marketplace/_app.json.jbuilder +4 -0
- data/app/views/mno_enterprise/jpi/v1/marketplace/index.json.jbuilder +1 -2
- data/app/views/mno_enterprise/jpi/v1/marketplace/show.json.jbuilder +1 -1
- data/app/views/mno_enterprise/jpi/v1/organizations/_current_user.json.jbuilder +1 -1
- data/app/views/mno_enterprise/jpi/v1/organizations/_invoices.json.jbuilder +3 -2
- data/app/views/mno_enterprise/jpi/v1/organizations/_member.json.jbuilder +2 -2
- data/app/views/mno_enterprise/jpi/v1/organizations/_organization.json.jbuilder +2 -2
- data/app/views/mno_enterprise/jpi/v1/teams/_team.json.jbuilder +11 -5
- data/app/views/mno_enterprise/pages/terms.html.haml +219 -0
- data/app/views/mno_enterprise/provision/_select_organization.html.haml +6 -2
- data/config/initializers/devise.rb +31 -9
- data/config/initializers/devise_log.rb +4 -4
- data/config/routes.rb +41 -6
- data/lib/mno_enterprise/api.rb +1 -0
- data/lib/mno_enterprise/audit_events_listener.rb +28 -0
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb +45 -0
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb +14 -4
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/alerts_controller.rb +76 -0
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb +49 -23
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/kpis_controller.rb +167 -0
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb +33 -17
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb +32 -0
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/organizations_controller.rb +68 -28
- data/lib/mno_enterprise/concerns/controllers/jpi/v1/teams_controller.rb +92 -0
- data/lib/mno_enterprise/concerns/controllers/pages_controller.rb +17 -3
- data/lib/mno_enterprise/concerns/controllers/provision_controller.rb +17 -2
- data/lib/mno_enterprise/concerns/mailers/system_notification_mailer.rb +27 -3
- data/lib/mno_enterprise/event_logger.rb +34 -16
- data/lib/mno_enterprise/intercom_events_listener.rb +96 -0
- data/spec/controllers/mno_enterprise/auth/confirmation_controller_spec.rb +28 -0
- data/spec/controllers/mno_enterprise/auth/omniauth_callback_controller_spec.rb +34 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller_spec.rb +45 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller_spec.rb +45 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller_spec.rb +31 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/app_reviews_controller_spec.rb +103 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/audit_events_controller_spec.rb +4 -15
- data/spec/controllers/mno_enterprise/jpi/v1/admin/cloud_apps_controller_spec.rb +12 -3
- data/spec/controllers/mno_enterprise/jpi/v1/admin/invites_controller_spec.rb +4 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/invoices_controller_spec.rb +15 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb +17 -1
- data/spec/controllers/mno_enterprise/jpi/v1/admin/tenant_invoices_controller_spec.rb +5 -0
- data/spec/controllers/mno_enterprise/jpi/v1/admin/users_controller_spec.rb +30 -16
- data/spec/controllers/mno_enterprise/jpi/v1/app_answers_controller_spec.rb +74 -0
- data/spec/controllers/mno_enterprise/jpi/v1/app_comments_controller_spec.rb +74 -0
- data/spec/controllers/mno_enterprise/jpi/v1/app_feedbacks_controller_spec.rb +84 -0
- data/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb +36 -22
- data/spec/controllers/mno_enterprise/jpi/v1/app_questions_controller_spec.rb +80 -0
- data/spec/controllers/mno_enterprise/jpi/v1/app_reviews_controller_spec.rb +107 -0
- data/spec/controllers/mno_enterprise/jpi/v1/current_users_controller_spec.rb +16 -1
- data/spec/controllers/mno_enterprise/jpi/v1/impac/alerts_controller_spec.rb +82 -0
- data/spec/controllers/mno_enterprise/jpi/v1/impac/kpis_controller_spec.rb +147 -10
- data/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb +39 -0
- data/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb +19 -26
- data/spec/controllers/mno_enterprise/jpi/v1/organizations_controller_spec.rb +248 -303
- data/spec/controllers/mno_enterprise/jpi/v1/team_controller_spec.rb +4 -1
- data/spec/controllers/mno_enterprise/pages_controller_spec.rb +21 -0
- data/spec/controllers/mno_enterprise/provision_controller_spec.rb +65 -22
- data/spec/controllers/mno_enterprise/webhook/o_auth_controller_spec.rb +1 -1
- data/spec/jobs/mno_enterprise/event_logger_job_spec.rb +11 -0
- data/spec/lib/mno_enterprise/audit_events_listener_spec.rb +28 -0
- data/spec/lib/mno_enterprise/intercom_events_listener_spec.rb +110 -0
- data/spec/mailer/mno_enterprise/system_notification_mailer_spec.rb +81 -46
- data/spec/routing/mno_enterprise/jpi/v1/admin/app_instances_controller_routing_spec.rb +11 -0
- data/spec/routing/mno_enterprise/jpi/v1/admin/app_reviews_controller_routing_spec.rb +19 -0
- data/spec/routing/mno_enterprise/jpi/v1/app_instances_controller_routing_spec.rb +9 -2
- data/spec/routing/mno_enterprise/jpi/v1/app_reviews_controller_routing_spec.rb +15 -0
- data/spec/routing/mno_enterprise/jpi/v1/current_users_controller_routing_spec.rb +5 -0
- data/spec/routing/mno_enterprise/jpi/v1/impac/alerts_controller_routing_spec.rb +24 -0
- data/spec/routing/mno_enterprise/jpi/v1/impac/dashboards_controller_routing_spec.rb +28 -0
- data/spec/routing/mno_enterprise/jpi/v1/impac/kpis_controller_routing_spec.rb +17 -11
- data/spec/routing/mno_enterprise/jpi/v1/impac/widgets_controller_routing_spec.rb +24 -0
- data/spec/routing/mno_enterprise/jpi/v1/marketplace_controller_routing_spec.rb +2 -2
- data/spec/routing/mno_enterprise/pages_controller_routing_spec.rb +4 -0
- metadata +178 -9
- data/app/controllers/mno_enterprise/jpi/v1/industry_bundle_controller.rb +0 -25
- data/app/controllers/mno_enterprise/jpi/v1/shopping_cart_controller.rb +0 -93
- data/spec/lib/mno_enterprise/event_logger_spec.rb +0 -28
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module MnoEnterprise
|
4
|
+
describe Jpi::V1::AppQuestionsController, type: :controller do
|
5
|
+
include MnoEnterprise::TestingSupport::JpiV1TestHelper
|
6
|
+
render_views
|
7
|
+
routes { MnoEnterprise::Engine.routes }
|
8
|
+
before { request.env["HTTP_ACCEPT"] = 'application/json' }
|
9
|
+
|
10
|
+
|
11
|
+
#===============================================
|
12
|
+
# Assignments
|
13
|
+
#===============================================
|
14
|
+
let(:user) { build(:user) }
|
15
|
+
before { api_stub_for(get: "/users/#{user.id}", response: from_api(user)) }
|
16
|
+
before { sign_in user }
|
17
|
+
|
18
|
+
let(:app) { build(:app) }
|
19
|
+
let(:question_answer_1) { build(:app_answer) }
|
20
|
+
let(:question_answer_2) { build(:app_answer) }
|
21
|
+
let(:app_question) { build(:app_question, answers: [question_answer_1, question_answer_2]) }
|
22
|
+
let(:expected_hash_for_answer_1) do
|
23
|
+
attrs = %w(id description status user_id user_name organization_id organization_name app_id question_id app_name user_admin_role edited edited_by_name edited_by_admin_role edited_by_id)
|
24
|
+
question_answer_1.attributes.slice(*attrs).merge({'created_at' => question_answer_1.created_at.as_json, 'updated_at' => question_answer_1.updated_at.as_json})
|
25
|
+
end
|
26
|
+
let(:expected_hash_for_answer_2) do
|
27
|
+
attrs = %w(id description status user_id user_name organization_id organization_name app_id question_id app_name user_admin_role edited edited_by_name edited_by_admin_role edited_by_id)
|
28
|
+
question_answer_2.attributes.slice(*attrs).merge({'created_at' => question_answer_2.created_at.as_json, 'updated_at' => question_answer_2.updated_at.as_json})
|
29
|
+
end
|
30
|
+
let(:expected_array_for_answers) { [expected_hash_for_answer_1, expected_hash_for_answer_2] }
|
31
|
+
let(:expected_hash_for_question) do
|
32
|
+
attrs = %w(id description status user_id user_name organization_id organization_name app_id app_name user_admin_role answers edited edited_by_name edited_by_admin_role edited_by_id)
|
33
|
+
app_question.attributes.slice(*attrs).merge({'created_at' => app_question.created_at.as_json, 'updated_at' => app_question.updated_at.as_json, 'answers' => expected_array_for_answers})
|
34
|
+
end
|
35
|
+
let(:expected_hash_for_questions) do
|
36
|
+
{
|
37
|
+
'app_questions' => [expected_hash_for_question],
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
before do
|
42
|
+
api_stub_for(get: "/apps/#{app.id}", response: from_api(app))
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'GET #index' do
|
46
|
+
|
47
|
+
before do
|
48
|
+
api_stub_for(get: "/app_questions?filter[reviewable_id]=#{app.id}", response: from_api([app_question]))
|
49
|
+
end
|
50
|
+
|
51
|
+
subject { get :index, id: app.id }
|
52
|
+
|
53
|
+
it_behaves_like "jpi v1 protected action"
|
54
|
+
|
55
|
+
it_behaves_like "a paginated action"
|
56
|
+
|
57
|
+
it 'renders the list of reviews' do
|
58
|
+
subject
|
59
|
+
expect(JSON.parse(response.body)).to eq(expected_hash_for_questions)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'POST #create', focus: true do
|
64
|
+
let(:params) { {organization_id: 1, description: 'A Review', foo: 'bar'} }
|
65
|
+
|
66
|
+
before do
|
67
|
+
api_stub_for(post: "/app_questions", response: from_api(app_question))
|
68
|
+
api_stub_for(get: "/app_questions/#{app_question.id}", response: from_api(app_question))
|
69
|
+
end
|
70
|
+
|
71
|
+
subject { post :create, id: app.id, app_question: params }
|
72
|
+
|
73
|
+
it_behaves_like "jpi v1 protected action"
|
74
|
+
|
75
|
+
it 'renders the new review' do
|
76
|
+
expect(JSON.parse(subject.body)).to include('app_question' => expected_hash_for_question)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module MnoEnterprise
|
4
|
+
describe Jpi::V1::AppReviewsController, type: :controller do
|
5
|
+
include MnoEnterprise::TestingSupport::JpiV1TestHelper
|
6
|
+
render_views
|
7
|
+
routes { MnoEnterprise::Engine.routes }
|
8
|
+
before { request.env["HTTP_ACCEPT"] = 'application/json' }
|
9
|
+
|
10
|
+
|
11
|
+
#===============================================
|
12
|
+
# Assignments
|
13
|
+
#===============================================
|
14
|
+
let(:user) { build(:user) }
|
15
|
+
before { api_stub_for(get: "/users/#{user.id}", response: from_api(user)) }
|
16
|
+
before { sign_in user }
|
17
|
+
|
18
|
+
let(:app) { build(:app) }
|
19
|
+
let(:app_review) { build(:app_review) }
|
20
|
+
let(:expected_hash_for_review) do
|
21
|
+
attrs = %w(id rating description status user_id user_name organization_id organization_name app_id app_name json.user_admin_role user_admin_role edited edited_by_name edited_by_admin_role edited_by_id)
|
22
|
+
app_review.attributes.slice(*attrs).merge({'created_at' => app_review.created_at.as_json, 'updated_at' => app_review.updated_at.as_json})
|
23
|
+
end
|
24
|
+
let(:expected_hash_for_reviews) do
|
25
|
+
{
|
26
|
+
'app_reviews' => [expected_hash_for_review],
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
api_stub_for(get: "/apps/#{app.id}", response: from_api(app))
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'GET #index' do
|
35
|
+
|
36
|
+
before do
|
37
|
+
api_stub_for(get: "/app_reviews?filter[reviewable_id]=#{app.id}", response: from_api([app_review]))
|
38
|
+
end
|
39
|
+
|
40
|
+
subject { get :index, id: app.id }
|
41
|
+
|
42
|
+
it_behaves_like "jpi v1 protected action"
|
43
|
+
|
44
|
+
it_behaves_like "a paginated action"
|
45
|
+
|
46
|
+
it 'renders the list of reviews' do
|
47
|
+
subject
|
48
|
+
expect(JSON.parse(response.body)).to eq(expected_hash_for_reviews)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'POST #create', focus: true do
|
53
|
+
let(:params) { {organization_id: 1, description: 'A Review', rating: 5, foo: 'bar'} }
|
54
|
+
let(:app_review) { build(:app_review) }
|
55
|
+
|
56
|
+
before do
|
57
|
+
api_stub_for(post: "/app_reviews", response: from_api(app_review))
|
58
|
+
api_stub_for(get: "/app_reviews/#{app_review.id}", response: from_api(app_review))
|
59
|
+
end
|
60
|
+
|
61
|
+
subject { post :create, id: app.id, app_review: params }
|
62
|
+
|
63
|
+
it_behaves_like "jpi v1 protected action"
|
64
|
+
|
65
|
+
it 'renders the new review' do
|
66
|
+
expect(JSON.parse(subject.body)).to include('app_review' => expected_hash_for_review)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'renders the new average rating' do
|
70
|
+
expect(JSON.parse(subject.body)).to include('average_rating' => app.average_rating)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'PATCH #update', focus: true do
|
75
|
+
let(:params) { {description: 'A Review 2', rating: 1} }
|
76
|
+
let(:app_review) { build(:app_review, user_id: user.id) }
|
77
|
+
|
78
|
+
before do
|
79
|
+
api_stub_for(put: "/app_reviews/#{app_review.id}", response: from_api(app_review))
|
80
|
+
api_stub_for(get: "/app_reviews/#{app_review.id}", response: from_api(app_review))
|
81
|
+
end
|
82
|
+
|
83
|
+
subject { put :update, id: app.id, review_id: app_review.id, app_review: params }
|
84
|
+
|
85
|
+
it 'renders the new review' do
|
86
|
+
expect(JSON.parse(subject.body)).to include('app_review' => expected_hash_for_review)
|
87
|
+
expect(JSON.parse(subject.body)).to include('average_rating' => app.average_rating)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'DELETE #destroy', focus: true do
|
92
|
+
let(:app_review) { build(:app_review, user_id: user.id) }
|
93
|
+
|
94
|
+
before do
|
95
|
+
api_stub_for(delete: "/app_reviews/#{app_review.id}", response: from_api(app_review))
|
96
|
+
api_stub_for(get: "/app_reviews/#{app_review.id}", response: from_api(app_review))
|
97
|
+
end
|
98
|
+
|
99
|
+
subject { delete :destroy, id: app.id, review_id: app_review.id }
|
100
|
+
|
101
|
+
it 'renders the new review' do
|
102
|
+
expect(JSON.parse(subject.body)).to include('app_review' => expected_hash_for_review)
|
103
|
+
expect(JSON.parse(subject.body)).to include('average_rating' => app.average_rating)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -26,6 +26,8 @@ module MnoEnterprise
|
|
26
26
|
'created_at' => res.created_at ? res.created_at.iso8601 : nil,
|
27
27
|
'company' => res.company,
|
28
28
|
'phone' => res.phone,
|
29
|
+
'api_secret' => res.api_secret,
|
30
|
+
'api_key' => res.api_key,
|
29
31
|
'phone_country_code' => res.phone_country_code,
|
30
32
|
'country_code' => res.geo_country_code || 'US',
|
31
33
|
'website' => res.website,
|
@@ -54,13 +56,15 @@ module MnoEnterprise
|
|
54
56
|
'token' => res.deletion_request.token
|
55
57
|
}
|
56
58
|
end
|
59
|
+
|
60
|
+
hash['kpi_enabled'] = !!res.kpi_enabled
|
57
61
|
end
|
58
62
|
|
59
63
|
hash
|
60
64
|
end
|
61
65
|
|
62
66
|
# Stub user retrieval
|
63
|
-
let!(:user) { build(:user, :with_deletion_request, :with_organizations) }
|
67
|
+
let!(:user) { build(:user, :with_deletion_request, :with_organizations, :kpi_enabled) }
|
64
68
|
before { api_stub_for(get: "/users/#{user.id}", response: from_api(user)) }
|
65
69
|
|
66
70
|
describe "GET #show" do
|
@@ -111,6 +115,17 @@ module MnoEnterprise
|
|
111
115
|
end
|
112
116
|
end
|
113
117
|
|
118
|
+
describe 'PUT #register_developer' do
|
119
|
+
before { api_stub_for(put: "/users/#{user.id}", response: from_api(user)) }
|
120
|
+
before { sign_in user }
|
121
|
+
subject { put :register_developer}
|
122
|
+
|
123
|
+
describe 'logged in' do
|
124
|
+
before { subject }
|
125
|
+
it { expect(response).to be_success }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
114
129
|
describe 'PUT #update_password' do
|
115
130
|
let(:attrs) { {current_password: 'password', password: 'blablabla', password_confirmation: 'blablabla'} }
|
116
131
|
before { api_stub_for(put: "/users/#{user.id}", response: from_api(user)) }
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module MnoEnterprise
|
4
|
+
describe Jpi::V1::Impac::AlertsController, type: :controller do
|
5
|
+
include MnoEnterprise::TestingSupport::JpiV1TestHelper
|
6
|
+
render_views
|
7
|
+
routes { MnoEnterprise::Engine.routes }
|
8
|
+
before { request.env["HTTP_ACCEPT"] = 'application/json' }
|
9
|
+
|
10
|
+
# Stub ability
|
11
|
+
let!(:ability) { stub_ability }
|
12
|
+
before { allow(ability).to receive(:can?).with(any_args).and_return(true) }
|
13
|
+
|
14
|
+
# Stub user and user call
|
15
|
+
let!(:user) { build(:user) }
|
16
|
+
before { api_stub_for(get: "/users/#{user.id}", response: from_api(user)) }
|
17
|
+
before { sign_in user }
|
18
|
+
|
19
|
+
let(:kpi) { build(:impac_kpi) }
|
20
|
+
let(:alert) { build(:impac_alert, kpi: kpi) }
|
21
|
+
let(:alert_hash) { from_api(alert)[:data].except(:kpi) }
|
22
|
+
|
23
|
+
describe 'GET #index' do
|
24
|
+
before { api_stub_for(get: "/users/#{user.id}/alerts", response: from_api([alert])) }
|
25
|
+
subject { get :index }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'POST #create' do
|
29
|
+
before { api_stub_for(get: "/kpis/#{kpi.id}", response: from_api(kpi)) }
|
30
|
+
before { api_stub_for(post: "/users/#{user.id}/alerts", response: from_api(alert)) }
|
31
|
+
before { api_stub_for(get: "/users/#{user.id}/alerts", response: from_api([])) }
|
32
|
+
|
33
|
+
subject { post :create, kpi_id: kpi.id, alert: alert_hash }
|
34
|
+
|
35
|
+
it_behaves_like "jpi v1 authorizable action"
|
36
|
+
|
37
|
+
it "creates and assigns the alert" do
|
38
|
+
subject
|
39
|
+
expect(assigns(:alert)).to eq(alert)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "attaches the alert to the kpi" do
|
43
|
+
subject
|
44
|
+
expect(assigns(:alert).kpi).to eq(kpi)
|
45
|
+
end
|
46
|
+
|
47
|
+
it { subject; expect(response.code).to eq('200') }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'PUT #update' do
|
51
|
+
let(:update_alert_hash) { {title: 'test', webhook: 'test', sent: true, forbidden: 'test'} }
|
52
|
+
let(:updated_alert) { build(:impac_alert, kpi: kpi, title: 'test', webhook: 'test', sent: true) }
|
53
|
+
|
54
|
+
before { api_stub_for(get: "/alerts/#{alert.id}", response: from_api(alert)) }
|
55
|
+
before { api_stub_for(put: "/alerts/#{alert.id}", response: from_api(updated_alert)) }
|
56
|
+
|
57
|
+
subject { put :update, id: alert.id, alert: update_alert_hash }
|
58
|
+
|
59
|
+
it_behaves_like "jpi v1 authorizable action"
|
60
|
+
|
61
|
+
it "assigns the alert" do
|
62
|
+
subject
|
63
|
+
expect(assigns(:alert)).to eq(updated_alert)
|
64
|
+
end
|
65
|
+
|
66
|
+
it { subject; expect(response.code).to eq('200') }
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'DELETE #destroy' do
|
70
|
+
before { api_stub_for(get: "/alerts/#{alert.id}", response: from_api(alert)) }
|
71
|
+
before { api_stub_for(get: "/kpis/#{kpi.id}", response: from_api(kpi)) }
|
72
|
+
before { api_stub_for(delete: "/alerts/#{alert.id}", response: from_api([])) }
|
73
|
+
|
74
|
+
subject { delete :destroy, id: alert.id }
|
75
|
+
|
76
|
+
it_behaves_like "jpi v1 authorizable action"
|
77
|
+
|
78
|
+
it { subject; expect(response.code).to eq('200') }
|
79
|
+
it { subject; expect(JSON.parse(response.body)).to eq({"deleted" => {"service" => alert.service}}) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -17,18 +17,76 @@ module MnoEnterprise
|
|
17
17
|
before { sign_in user }
|
18
18
|
|
19
19
|
let(:dashboard) { build(:impac_dashboard) }
|
20
|
+
|
21
|
+
# TODO KPI DISABLED TEST CASES
|
22
|
+
|
23
|
+
# Stub the dashboard owner
|
20
24
|
before { allow_any_instance_of(MnoEnterprise::Impac::Dashboard).to receive(:owner).and_return(user) }
|
21
|
-
before { api_stub_for(get: "/dashboards/#{dashboard.id}", response: from_api(dashboard)) }
|
22
25
|
|
23
|
-
let(:
|
26
|
+
let(:kpi_targets) { { evolution: [{max: "20"}] } }
|
27
|
+
let(:kpi) { build(:impac_kpi, dashboard: dashboard, targets: kpi_targets) }
|
24
28
|
let(:kpi_hash) { from_api(kpi)[:data].except(:dashboard) }
|
25
29
|
|
26
|
-
|
27
|
-
|
30
|
+
let(:alert) { build(:impac_alert, kpi: kpi) }
|
31
|
+
let(:alerts_hashes) { [from_api(alert)[:data]] }
|
32
|
+
|
33
|
+
describe 'GET index' do
|
34
|
+
let(:params) { { 'metadata' => {'organization_ids' => ['some_id']}, 'opts' => {'some' => 'opts'} } }
|
35
|
+
subject { get :index, metadata: params['metadata'], opts: params['opts'] }
|
28
36
|
|
37
|
+
let(:impac_available_kpis) do
|
38
|
+
[
|
39
|
+
{"name"=>"Debtor Due Days", "endpoint"=>"invoicing/due_days/debtor", "watchables"=>["max", "average"], "attachables"=>nil, "target_placeholders"=>{"max"=>{"mode"=>"max", "value"=>90, "unit"=>"days"}, "average"=>{"mode"=>"max", "value"=>30, "unit"=>"days"}}},
|
40
|
+
{"name"=>"Account Balance", "endpoint"=>"accounting/balance", "watchables"=>["balance"], "attachables"=>["accounts/balance"], "target_placeholders"=>{"balance"=>{"mode"=>"min", "value"=>15000, "unit"=>"currency"}}}
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:expected_result) do
|
45
|
+
{
|
46
|
+
"kpis" => [
|
47
|
+
{"name"=>"Debtor Due Days Max", "endpoint"=>"invoicing/due_days/debtor", "watchables"=>["max"], "attachables"=>nil, "target_placeholders"=>{"max"=>{"mode"=>"max", "value"=>90, "unit"=>"days"}}},
|
48
|
+
{"name"=>"Debtor Due Days Average", "endpoint"=>"invoicing/due_days/debtor", "watchables"=>["average"], "attachables"=>nil, "target_placeholders"=>{"average"=>{"mode"=>"max", "value"=>30, "unit"=>"days"}}},
|
49
|
+
{"name"=>"Account Balance", "endpoint"=>"accounting/balance", "watchables"=>["balance"], "attachables"=>["accounts/balance"], "target_placeholders"=>{"balance"=>{"mode"=>"min", "value"=>15000, "unit"=>"currency"}}},
|
50
|
+
]
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:auth) { { username: 'username', password: 'password' } }
|
55
|
+
before { allow(MnoEnterprise::ImpacClient).to receive(:send_get).with('/api/v2/kpis', params, basic_auth: auth).and_return('kpis' => impac_available_kpis) }
|
56
|
+
before { allow(MnoEnterprise).to receive(:tenant_id).and_return(auth[:username]) }
|
57
|
+
before { allow(MnoEnterprise).to receive(:tenant_key).and_return(auth[:password]) }
|
58
|
+
|
59
|
+
it { subject; expect(response.code).to eq('200') }
|
60
|
+
|
61
|
+
it "successfully discovers and customises available kpis" do
|
62
|
+
expect(MnoEnterprise::ImpacClient).to receive(:send_get)
|
63
|
+
subject
|
64
|
+
expect(JSON.parse(response.body)).to eq(expected_result)
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when impac api request raises an error" do
|
68
|
+
before { allow(MnoEnterprise::ImpacClient).to receive(:send_get).and_raise }
|
69
|
+
|
70
|
+
it "rescues responding with an error message" do
|
71
|
+
subject
|
72
|
+
expect(JSON.parse(response.body)).to include('message')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
29
76
|
|
30
77
|
describe 'POST #create' do
|
31
78
|
subject { post :create, dashboard_id: dashboard.id, kpi: kpi_hash }
|
79
|
+
let (:kpi_targets) { {} }
|
80
|
+
|
81
|
+
before do
|
82
|
+
api_stub_for(get: "/dashboards/#{dashboard.id}", response: from_api(dashboard))
|
83
|
+
api_stub_for(post: "/dashboards/#{dashboard.id}/kpis", response: from_api(kpi))
|
84
|
+
api_stub_for(get: "/dashboards/#{dashboard.id}/kpis", response: from_api([]))
|
85
|
+
api_stub_for(get: "/kpis/#{kpi.id}", response: from_api(kpi)) # kpi.reload
|
86
|
+
# TODO: this call should not happen as alerts should be wrapped into the kpi object
|
87
|
+
api_stub_for(get: "/kpis/#{kpi.id}/alerts", response: from_api(alerts_hashes))
|
88
|
+
end
|
89
|
+
|
32
90
|
it_behaves_like "jpi v1 authorizable action"
|
33
91
|
|
34
92
|
it ".dashboard retrieves the correct dashboard" do
|
@@ -41,17 +99,35 @@ module MnoEnterprise
|
|
41
99
|
expect(assigns(:kpi)).to eq(kpi)
|
42
100
|
end
|
43
101
|
|
102
|
+
context "when there are kpi targets" do
|
103
|
+
let(:kpi_targets) { { evolution: [{max: "20"}] } }
|
104
|
+
|
105
|
+
before do
|
106
|
+
api_stub_for(post: "/users/#{user.id}/alerts", response: from_api(alert))
|
107
|
+
api_stub_for(get: "/users/#{user.id}/alerts", response: from_api({}))
|
108
|
+
end
|
109
|
+
|
110
|
+
it "creates kpi alerts" do
|
111
|
+
subject
|
112
|
+
expect(assigns(:kpi).alerts).to eq([alert])
|
113
|
+
expect(response.code).to eq('200')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
44
117
|
it { subject; expect(response.code).to eq('200') }
|
45
|
-
it { subject; expect(JSON.parse(response.body)).to eq(kpi_hash) }
|
46
118
|
end
|
47
119
|
|
48
120
|
describe 'PUT #update' do
|
49
121
|
let(:kpi_hash) { from_api(kpi)[:data].except(:dashboard).merge(element_watched: 'New Watchable') }
|
122
|
+
let(:params) { {} }
|
50
123
|
|
51
|
-
subject { put :update, id: kpi.id, kpi: kpi_hash }
|
124
|
+
subject { put :update, id: kpi.id, kpi: kpi_hash.merge(params) }
|
52
125
|
|
53
|
-
before
|
54
|
-
|
126
|
+
before do
|
127
|
+
api_stub_for(get: "/kpis/#{kpi.id}", response: from_api(kpi))
|
128
|
+
api_stub_for(put: "/kpis/#{kpi.id}", response: kpi_hash)
|
129
|
+
api_stub_for(get: "/kpis/#{kpi.id}/alerts", response: from_api(alerts_hashes))
|
130
|
+
end
|
55
131
|
|
56
132
|
before { kpi.save }
|
57
133
|
|
@@ -60,10 +136,71 @@ module MnoEnterprise
|
|
60
136
|
it "updates the kpi" do
|
61
137
|
subject
|
62
138
|
expect(assigns(:kpi).element_watched).to eq('New Watchable')
|
139
|
+
expect(response.code).to eq('200')
|
63
140
|
end
|
64
141
|
|
65
|
-
|
66
|
-
|
142
|
+
context "target set for the first time" do
|
143
|
+
let(:kpi_targets) { nil }
|
144
|
+
let(:params) { { targets: {evolution: [{max:'20'}]} } }
|
145
|
+
|
146
|
+
before do
|
147
|
+
api_stub_for(post: "/users/#{user.id}/alerts", response: from_api(alert))
|
148
|
+
api_stub_for(get: "/users/#{user.id}/alerts", response: from_api({}))
|
149
|
+
end
|
150
|
+
|
151
|
+
it "creates an alert" do
|
152
|
+
subject
|
153
|
+
expect(assigns(:kpi).alerts).to eq([alert])
|
154
|
+
expect(response.code).to eq('200')
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "when targets have changed" do
|
159
|
+
let(:alert) { build(:impac_alert, kpi: kpi, sent: true) }
|
160
|
+
let(:params) { { targets: {evolution: [{max:'30'}]} } }
|
161
|
+
|
162
|
+
before { api_stub_for(put: "/alerts/#{alert.id}", response: from_api({})) }
|
163
|
+
|
164
|
+
it "updates the sent status of all the kpi's alerts" do
|
165
|
+
subject
|
166
|
+
expect(assigns(:kpi).alerts).to eq([alert])
|
167
|
+
expect(response.code).to eq('200')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "when a kpi has no targets, nor is being updated with any" do
|
172
|
+
let(:kpi_targets) { nil }
|
173
|
+
let(:params) { { targets: {} } }
|
174
|
+
|
175
|
+
before { api_stub_for(delete: "/alerts/#{alert.id}", response: from_api({})) }
|
176
|
+
|
177
|
+
it "destroys the kpi's alerts" do
|
178
|
+
subject
|
179
|
+
expect(response.code).to eq('200')
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context "when no targets are given / targets are nil" do
|
184
|
+
let(:kpi) { build(:impac_kpi, dashboard: dashboard, targets: kpi_targets, settings: { currency: 'GBP' }) }
|
185
|
+
let(:params) { { targets: nil } }
|
186
|
+
|
187
|
+
it "does not remove the kpi targets" do
|
188
|
+
subject
|
189
|
+
expect(assigns(:kpi).targets).to eq(kpi_targets.deep_stringify_keys)
|
190
|
+
expect(response.code).to eq('200')
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "when no extra_params are given / extra_params are nil" do
|
195
|
+
let(:kpi) { build(:impac_kpi, dashboard: dashboard, targets: kpi_targets, extra_params: ['some-param'], settings: { currency: 'GBP' }) }
|
196
|
+
let(:params) { { extra_params: nil } }
|
197
|
+
|
198
|
+
it "does not remove the kpi extra_params" do
|
199
|
+
subject
|
200
|
+
expect(assigns(:kpi).extra_params).to eq(['some-param'])
|
201
|
+
expect(response.code).to eq('200')
|
202
|
+
end
|
203
|
+
end
|
67
204
|
end
|
68
205
|
|
69
206
|
describe 'DELETE #destroy' do
|