mumuki-laboratory 5.0.12 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +339 -0
- data/app/assets/javascripts/application/bridge.js +36 -7
- data/app/assets/javascripts/application/kids.js +92 -7
- data/app/assets/javascripts/application/submission.js +2 -1
- data/app/assets/stylesheets/application/modules/_highlight.scss +8 -0
- data/app/assets/stylesheets/application/modules/_kids.scss +92 -27
- data/app/controllers/api/base_controller.rb +23 -0
- data/app/controllers/api/courses_controller.rb +26 -0
- data/app/controllers/api/organizations_controller.rb +28 -0
- data/app/controllers/api/roles_controller.rb +47 -0
- data/app/controllers/api/students_controller.rb +9 -0
- data/app/controllers/api/teachers_controller.rb +9 -0
- data/app/controllers/api/users_controller.rb +18 -0
- data/app/controllers/assets_controller.rb +2 -1
- data/app/controllers/concerns/on_base_organization_only.rb +11 -0
- data/app/controllers/concerns/organizations_controller_template.rb +34 -0
- data/app/controllers/concerns/users_controller_template.rb +28 -0
- data/app/controllers/concerns/with_api_errors.rb +37 -0
- data/app/controllers/concerns/with_authorization.rb +19 -0
- data/app/controllers/concerns/with_errors_filter.rb +32 -0
- data/app/helpers/reset_button_helper.rb +1 -1
- data/app/models/api_client.rb +27 -0
- data/app/models/api_client_spec.rb +6 -0
- data/app/models/concerns/with_assignments.rb +4 -1
- data/app/models/course.rb +4 -6
- data/app/models/exercise/challenge.rb +5 -6
- data/app/models/language.rb +1 -1
- data/app/models/organization.rb +4 -0
- data/app/models/user.rb +22 -1
- data/app/views/exercise_solutions/_kids_results_button.html.erb +11 -0
- data/app/views/exercise_solutions/_results.html.erb +1 -7
- data/app/views/exercise_solutions/_results_button.html.erb +7 -0
- data/app/views/layouts/_kids.html.erb +5 -2
- data/app/views/layouts/exercise_inputs/editors/_custom.html.erb +1 -0
- data/app/views/layouts/exercise_inputs/forms/_kids_form.html.erb +3 -0
- data/app/views/layouts/exercise_inputs/layouts/_input_kids.html.erb +3 -3
- data/app/views/layouts/modals/_kids_context.html.erb +0 -3
- data/app/views/layouts/modals/_kids_results.html.erb +2 -0
- data/config/routes.rb +23 -0
- data/db/migrate/20180129142749_add_api_client.rb +11 -0
- data/lib/mumuki/laboratory/controllers/results_rendering.rb +7 -1
- data/lib/mumuki/laboratory/extensions/string.rb +8 -0
- data/lib/mumuki/laboratory/locales/en.yml +4 -0
- data/lib/mumuki/laboratory/locales/es.yml +4 -0
- data/lib/mumuki/laboratory/locales/pt.yml +4 -0
- data/lib/mumuki/laboratory/mumukit/auth.rb +7 -0
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/public/amarillo_exito.svg +11 -0
- data/public/amarillo_fracaso.svg +5 -0
- data/public/compass_rose.svg +1417 -0
- data/spec/controllers/api_clients_controller.rb +26 -0
- data/spec/controllers/confirmations_controller_spec.rb +1 -1
- data/spec/controllers/courses_api_controller_spec.rb +28 -0
- data/spec/controllers/exercise_solutions_controller_spec.rb +1 -1
- data/spec/controllers/messages_controller_spec.rb +1 -1
- data/spec/controllers/organizations_api_controller_spec.rb +235 -0
- data/spec/controllers/students_api_controller_spec.rb +101 -0
- data/spec/controllers/users_api_controller_spec.rb +56 -0
- data/spec/dummy/db/schema.rb +9 -0
- data/spec/factories/api_client_factory.rb +18 -0
- data/spec/factories/course_factory.rb +9 -0
- data/spec/features/chapter_spec.rb +1 -1
- data/spec/features/complements_flow_spec.rb +1 -1
- data/spec/features/exams_flow_spec.rb +1 -1
- data/spec/features/exercise_flow_spec.rb +1 -1
- data/spec/features/guide_reset_spec.rb +1 -1
- data/spec/features/guides_flow_spec.rb +1 -1
- data/spec/features/home_public_flow_spec.rb +1 -1
- data/spec/features/lessons_flow_spec.rb +1 -1
- data/spec/features/links_flow_spec.rb +1 -1
- data/spec/features/login_flow_spec.rb +1 -1
- data/spec/features/profile_flow_spec.rb +1 -1
- data/spec/features/standard_flow_spec.rb +1 -1
- data/spec/helpers/application_helper_spec.rb +1 -1
- data/spec/helpers/email_helper_spec.rb +1 -1
- data/spec/helpers/exercise_input_helper_spec.rb +1 -1
- data/spec/helpers/with_breadcrumbs_spec.rb +1 -1
- data/spec/helpers/with_navigation_spec.rb +1 -1
- data/spec/models/assignment_spec.rb +1 -1
- data/spec/models/book_import_spec.rb +1 -1
- data/spec/models/book_spec.rb +1 -1
- data/spec/models/course_spec.rb +1 -1
- data/spec/models/event_generation_spec.rb +1 -1
- data/spec/models/exam_spec.rb +1 -1
- data/spec/models/exercise_spec.rb +11 -3
- data/spec/models/guide_spec.rb +1 -1
- data/spec/models/interactive_spec.rb +1 -1
- data/spec/models/lesson_spec.rb +1 -1
- data/spec/models/message_spec.rb +1 -1
- data/spec/models/navigation_spec.rb +1 -1
- data/spec/models/organization_spec.rb +1 -1
- data/spec/models/problem_spec.rb +1 -1
- data/spec/models/question_spec.rb +1 -1
- data/spec/models/reading_spec.rb +1 -1
- data/spec/models/solution_spec.rb +1 -1
- data/spec/models/usage_spec.rb +1 -1
- data/spec/models/user_changed_spec.rb +1 -1
- data/spec/models/user_spec.rb +5 -5
- data/spec/spec_helper.rb +19 -3
- metadata +37 -2
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ApiClientsController, type: :controller, organization_workspace: :base do
|
4
|
+
before { @request.env["HTTP_AUTHORIZATION"] = api_client.token }
|
5
|
+
let(:api_client) { create :api_client }
|
6
|
+
let(:api_client_json) do
|
7
|
+
{description: 'foo',
|
8
|
+
user_attributes: user_json
|
9
|
+
}
|
10
|
+
end
|
11
|
+
let(:user_json) do
|
12
|
+
{first_name: 'foo',
|
13
|
+
last_name: 'bar',
|
14
|
+
email: 'foo@bar.com',
|
15
|
+
permissions: {student: 'foo/*'}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
context 'post' do
|
19
|
+
before { post :create, params: { api_client: api_client_json }}
|
20
|
+
|
21
|
+
it { expect(response.status).to eq 200 }
|
22
|
+
it { expect(ApiClient.count).to eq 1 }
|
23
|
+
it { expect(ApiClient.first.user.permissions).to eq('student' => 'foo/*') }
|
24
|
+
it { expect(Apiclient.first.user.email).to eq 'foo@bar.com' }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Api::CoursesController, type: :controller, organization_workspace: :base do
|
4
|
+
before { set_api_client! }
|
5
|
+
let(:api_client) { create :api_client }
|
6
|
+
let(:course_json) do
|
7
|
+
{slug: 'test/bar',
|
8
|
+
shifts: %w(morning),
|
9
|
+
code: 'k2003',
|
10
|
+
days: %w(monday wednesday),
|
11
|
+
period: '2016',
|
12
|
+
description: 'test course'}
|
13
|
+
end
|
14
|
+
|
15
|
+
let!(:organization) { create :organization, name: 'test' }
|
16
|
+
|
17
|
+
context 'post' do
|
18
|
+
before { post :create, params: { course: course_json }}
|
19
|
+
|
20
|
+
it { expect(response.status).to eq 200 }
|
21
|
+
it { expect(Course.count).to eq 1 }
|
22
|
+
it { expect(Course.first.slug).to eq 'test/bar' }
|
23
|
+
it { expect(Course.first.organization).to eq(organization) }
|
24
|
+
it { expect(Course.first.shifts).to eq(%w(morning)) }
|
25
|
+
it { expect(Course.first.days).to eq(%w(monday wednesday)) }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Api::OrganizationsController, type: :controller, organization_workspace: :base do
|
4
|
+
def check_status!(status)
|
5
|
+
expect(response.status).to eq status
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'unauthenticated request' do
|
9
|
+
it { expect { get :index }.to raise_error 'missing authorization header' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'unauthenticated request' do
|
13
|
+
before { @request.env["HTTP_AUTHORIZATION"] = 'foo' }
|
14
|
+
it { expect { get :index }.to raise_error 'No Api Client found for Token' }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'authenticated request' do
|
18
|
+
let(:book) { create :book }
|
19
|
+
|
20
|
+
before { set_api_client! }
|
21
|
+
|
22
|
+
describe 'GET' do
|
23
|
+
let!(:public_organization) { create :organization, name: 'public' }
|
24
|
+
let!(:dot_organization) { create :organization, name: 'dot.org' }
|
25
|
+
let!(:private_organization) { create :organization, name: 'private', public: false }
|
26
|
+
let!(:another_private_organization) { create :organization, name: 'another_private', public: false }
|
27
|
+
|
28
|
+
context 'GET /organizations' do
|
29
|
+
context 'with wildcard permissions' do
|
30
|
+
before { get :index }
|
31
|
+
let(:api_client) { create :api_client, role: :janitor, grant: '*' }
|
32
|
+
let!(:body) { response.body.parse_json }
|
33
|
+
|
34
|
+
it { check_status! 200 }
|
35
|
+
|
36
|
+
it { expect(body[:organizations].map { |it| it[:name] }).to eq %w(base public dot.org private another_private) }
|
37
|
+
end
|
38
|
+
context 'with non-wildcard permissions' do
|
39
|
+
before { get :index }
|
40
|
+
let(:api_client) { create :api_client, role: :janitor, grant: 'public/*:private/*' }
|
41
|
+
let!(:body) { response.body.parse_json }
|
42
|
+
|
43
|
+
it { check_status! 200 }
|
44
|
+
|
45
|
+
it { expect(body[:organizations].map { |it| it[:name] }).to eq %w(public private) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'GET /organizations/:id' do
|
50
|
+
context 'with a public organization' do
|
51
|
+
before { get :show, params: {id: 'public'} }
|
52
|
+
|
53
|
+
context 'with a user without janitor permissions' do
|
54
|
+
let(:api_client) { create :api_client, role: :editor, grant: 'another_organization/*' }
|
55
|
+
|
56
|
+
it { check_status! 403 }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with a user with janitor' do
|
60
|
+
let(:api_client) { create :api_client, role: :janitor, grant: 'public/*' }
|
61
|
+
|
62
|
+
it { check_status! 200 }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'with an organization that has a dot in its name' do
|
67
|
+
before { get :show, params: {id: 'dot.org'} }
|
68
|
+
|
69
|
+
let(:api_client) { create :api_client, role: :janitor, grant: 'dot.org/*' }
|
70
|
+
it { check_status! 200 }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with a private organization' do
|
74
|
+
before { get :show, params: {id: 'private'} }
|
75
|
+
|
76
|
+
context 'with a user without permissions' do
|
77
|
+
let(:api_client) { create :api_client, role: :editor, grant: 'another_organization/*' }
|
78
|
+
|
79
|
+
it { check_status! 403 }
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'with a user with permissions' do
|
83
|
+
let(:api_client) { create :api_client, role: :janitor, grant: 'private/*' }
|
84
|
+
|
85
|
+
it { check_status! 200 }
|
86
|
+
it { expect(response.body.parse_json).to json_like(private_organization.as_platform_json) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'with a non-existing organization' do
|
91
|
+
before { get :show, params: {id: 'non-existing'} }
|
92
|
+
let(:api_client) { create :api_client, role: :editor, grant: 'bleh/*' }
|
93
|
+
|
94
|
+
it { check_status! 404 }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'POST /organizations' do
|
100
|
+
before { post :create, params: {organization: organization_json} }
|
101
|
+
let(:organization_json) do
|
102
|
+
{contact_email: 'an_email@gmail.com',
|
103
|
+
name: 'a-name',
|
104
|
+
public: false,
|
105
|
+
book: book.slug,
|
106
|
+
locale: 'es'}
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'with the owner permissions' do
|
110
|
+
let(:api_client) { create :api_client, role: :owner, grant: '*' }
|
111
|
+
let(:organization) { Organization.find_by name: 'a-name' }
|
112
|
+
|
113
|
+
it { check_status! 200 }
|
114
|
+
it { expect(response.body.parse_json).to json_like(organization.as_platform_json) }
|
115
|
+
it { expect(Organization.count).to eq 2 }
|
116
|
+
it { expect(organization.name).to eq 'a-name' }
|
117
|
+
it { expect(organization.contact_email).to eq 'an_email@gmail.com' }
|
118
|
+
it { expect(organization.book).to eq book }
|
119
|
+
it { expect(organization.locale).to eq 'es' }
|
120
|
+
|
121
|
+
context 'with only mandatory values' do
|
122
|
+
it { expect(organization.public?).to eq false }
|
123
|
+
it { expect(organization.login_methods).to eq %w(user_pass) }
|
124
|
+
it { expect(organization.logo_url).to eq 'https://mumuki.io/logo-alt-large.png' }
|
125
|
+
it { expect(organization.theme_stylesheet).to eq '.defaultCssFromBase { css: red }' }
|
126
|
+
it { expect(organization.extension_javascript).to eq 'function jsFromBase() {}' }
|
127
|
+
it { expect(organization.terms_of_service).to eq nil }
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'with optional values' do
|
131
|
+
let(:organization_json) do
|
132
|
+
{contact_email: 'an_email@gmail.com',
|
133
|
+
name: 'a-name',
|
134
|
+
description: 'A description',
|
135
|
+
book: book.slug,
|
136
|
+
locale: 'es',
|
137
|
+
public: false,
|
138
|
+
login_methods: %w(facebook github),
|
139
|
+
logo_url: 'http://a-logo-url.com',
|
140
|
+
theme_stylesheet: '.theme { color: red }',
|
141
|
+
extension_javascript: 'window.a = function() { }',
|
142
|
+
terms_of_service: 'A TOS'}
|
143
|
+
end
|
144
|
+
|
145
|
+
it { expect(organization.public?).to eq false }
|
146
|
+
it { expect(organization.description).to eq 'A description' }
|
147
|
+
it { expect(organization.login_methods).to eq %w(facebook github) }
|
148
|
+
it { expect(organization.logo_url).to eq 'http://a-logo-url.com' }
|
149
|
+
it { expect(organization.theme_stylesheet).to eq ".theme { color: red }" }
|
150
|
+
it { expect(organization.extension_javascript).to eq "window.a = function() { }" }
|
151
|
+
it { expect(organization.terms_of_service).to eq 'A TOS' }
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'with missing values' do
|
155
|
+
let(:organization_json) do
|
156
|
+
{contact_email: 'an_email@gmail.com',
|
157
|
+
locale: 'blabla'}
|
158
|
+
end
|
159
|
+
let(:expected_errors) do
|
160
|
+
{
|
161
|
+
errors: {
|
162
|
+
name: ["can't be blank"],
|
163
|
+
locale: ['is not included in the list']
|
164
|
+
}
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
it { check_status! 400 }
|
169
|
+
it { expect(response.body.parse_json).to eq expected_errors }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'with owner permissions' do
|
174
|
+
let(:api_client) { create :api_client, role: :owner, grant: '*' }
|
175
|
+
|
176
|
+
it { check_status! 200 }
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
context 'with not-janitor permissions' do
|
181
|
+
let(:api_client) { create :api_client, role: :editor, grant: '*' }
|
182
|
+
|
183
|
+
it { check_status! 403 }
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe 'PUT /organizations/:id' do
|
188
|
+
let!(:organization) {
|
189
|
+
create :organization,
|
190
|
+
name: 'existing-organization',
|
191
|
+
contact_email: 'first_email@gmail.com',
|
192
|
+
terms_of_service: 'A TOS',
|
193
|
+
public: false,
|
194
|
+
login_methods: ['facebook', 'user_pass'],
|
195
|
+
book: book }
|
196
|
+
let(:updated_organizaton) { organization.reload }
|
197
|
+
let(:update_json) { {contact_email: 'second_email@gmail.com', immersive: true, locale: 'en'} }
|
198
|
+
|
199
|
+
context 'with the owner permissions' do
|
200
|
+
let(:api_client) { create :api_client, role: :owner, grant: 'existing-organization/*' }
|
201
|
+
before { put :update, params: {id: organization.name, organization: update_json} }
|
202
|
+
|
203
|
+
it { check_status! 200 }
|
204
|
+
it { expect(response.body.parse_json).to json_like(
|
205
|
+
book: book.slug,
|
206
|
+
name: "existing-organization",
|
207
|
+
profile: {
|
208
|
+
description: "a great org",
|
209
|
+
locale: 'en',
|
210
|
+
contact_email: "second_email@gmail.com",
|
211
|
+
terms_of_service: 'A TOS'
|
212
|
+
},
|
213
|
+
settings: {
|
214
|
+
login_methods: ["facebook", "user_pass"],
|
215
|
+
public: false,
|
216
|
+
immersive: true
|
217
|
+
},
|
218
|
+
theme: {
|
219
|
+
extension_javascript: 'function jsFromBase() {}',
|
220
|
+
theme_stylesheet: '.defaultCssFromBase { css: red }'
|
221
|
+
}) }
|
222
|
+
|
223
|
+
it { expect(updated_organizaton.name).to eq 'existing-organization' }
|
224
|
+
it { expect(updated_organizaton.contact_email).to eq 'second_email@gmail.com' }
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'with not-janitor permissions' do
|
228
|
+
let(:api_client) { create :api_client, role: :teacher, grant: 'existing-organization/*' }
|
229
|
+
before { put :update, params: {id: 'existing-organization', organization: update_json} }
|
230
|
+
|
231
|
+
it { check_status! 403 }
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
[:student, :teacher].each do |role|
|
4
|
+
|
5
|
+
describe "Api::#{role.capitalize}sController".constantize, type: :controller, organization_workspace: :base do
|
6
|
+
before { set_api_client! }
|
7
|
+
let(:api_client) { create :api_client, grant: 'anorganization/*' }
|
8
|
+
let(:json) { {
|
9
|
+
first_name: 'Agustin',
|
10
|
+
last_name: 'Pina',
|
11
|
+
email: 'agus@mumuki.org',
|
12
|
+
uid: 'agus@mumuki.org'
|
13
|
+
} }
|
14
|
+
|
15
|
+
let!(:organization) { create :organization, name: 'anorganization' }
|
16
|
+
let!(:course) { create :course, slug: 'anorganization/acode' }
|
17
|
+
|
18
|
+
context 'post' do
|
19
|
+
let(:params) { {role => json, organization: 'anorganization', course: 'acode'} }
|
20
|
+
|
21
|
+
context 'when user does not exist' do
|
22
|
+
|
23
|
+
before { post :create, params: params }
|
24
|
+
|
25
|
+
it { expect(response.status).to eq 200 }
|
26
|
+
it { expect(User.count).to eq 2 }
|
27
|
+
it { expect(User.last.last_name).to eq 'Pina' }
|
28
|
+
it { expect(User.last.first_name).to eq 'Agustin' }
|
29
|
+
it { expect(User.last.uid).to eq 'agus@mumuki.org' }
|
30
|
+
it { expect(User.last.email).to eq 'agus@mumuki.org' }
|
31
|
+
it { expect(User.last.permissions.has_permission? role, 'anorganization/acode').to be true }
|
32
|
+
|
33
|
+
end
|
34
|
+
context 'when user exist' do
|
35
|
+
context 'and have no permissions' do
|
36
|
+
before { create :user, json }
|
37
|
+
before { post :create, params: params }
|
38
|
+
it { expect(response.status).to eq 200 }
|
39
|
+
it { expect(User.count).to eq 2 }
|
40
|
+
it { expect(User.last.permissions.has_permission? role, 'anorganization/acode').to be true }
|
41
|
+
end
|
42
|
+
context 'and have permissions' do
|
43
|
+
before { create :user, json.merge(:permissions => {role => 'foo/bar'}) }
|
44
|
+
before { post :create, params: params }
|
45
|
+
it { expect(response.status).to eq 200 }
|
46
|
+
it { expect(User.count).to eq 2 }
|
47
|
+
it { expect(User.last.permissions.has_permission? role, 'anorganization/acode').to be true }
|
48
|
+
it { expect(User.last.permissions.has_permission? role, 'foo/bar').to be true }
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'attach' do
|
56
|
+
let(:params) { {uid: json[:uid], organization: 'anorganization', course: 'acode'} }
|
57
|
+
|
58
|
+
context 'when user does not exist' do
|
59
|
+
before { post :attach, params: params }
|
60
|
+
it { expect(response.status).to eq 404 }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when user exist' do
|
64
|
+
context 'and have no permissions' do
|
65
|
+
before { create :user, json }
|
66
|
+
before { post :attach, params: params }
|
67
|
+
it { expect(response.status).to eq 200 }
|
68
|
+
it { expect(User.last.permissions.has_permission? role, 'anorganization/acode').to be true }
|
69
|
+
end
|
70
|
+
context 'and have permissions' do
|
71
|
+
before { create :user, json.merge(:permissions => {role => 'foo/bar'}) }
|
72
|
+
before { post :attach, params: params }
|
73
|
+
it { expect(response.status).to eq 200 }
|
74
|
+
it { expect(User.last.permissions.has_permission? role, 'anorganization/acode').to be true }
|
75
|
+
it { expect(User.last.permissions.has_permission? role, 'foo/bar').to be true }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'detach' do
|
82
|
+
let(:params) { {uid: json[:uid], organization: 'anorganization', course: 'acode'} }
|
83
|
+
|
84
|
+
context 'when user does not exist' do
|
85
|
+
before { post :detach, params: params }
|
86
|
+
it { expect(response.status).to eq 404 }
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when user exist' do
|
90
|
+
context 'and have permissions' do
|
91
|
+
before { create :user, json.merge(:permissions => {role => 'anorganization/acode'}) }
|
92
|
+
before { post :detach, params: params }
|
93
|
+
it { expect(response.status).to eq 200 }
|
94
|
+
it { expect(User.last.permissions.has_permission? role, 'anorganization/acode').to be false }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Api::UsersController, type: :controller, organization_workspace: :base do
|
4
|
+
before { set_api_client! }
|
5
|
+
let(:api_client) { create :api_client }
|
6
|
+
let(:user_json) do
|
7
|
+
{
|
8
|
+
first_name: 'foo',
|
9
|
+
last_name: 'bar',
|
10
|
+
email: 'foo@bar.com',
|
11
|
+
permissions: {student: 'test/bar'},
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:owner_json) do
|
16
|
+
{
|
17
|
+
first_name: 'foo',
|
18
|
+
last_name: 'bar',
|
19
|
+
email: 'foo@bar.com',
|
20
|
+
permissions: {owner: '*'}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'post' do
|
25
|
+
before { post :create, params: {user: user_json} }
|
26
|
+
|
27
|
+
it { expect(response.status).to eq 200 }
|
28
|
+
it { expect(response.body.parse_json).to json_like({uid: 'foo@bar.com',
|
29
|
+
first_name: 'foo',
|
30
|
+
last_name: 'bar',
|
31
|
+
email: 'foo@bar.com',
|
32
|
+
permissions: {'student' => 'test/bar'},
|
33
|
+
image_url: 'user_shape.png'},
|
34
|
+
except: [:id, :created_at, :updated_at]) }
|
35
|
+
it { expect(User.count).to eq 2 }
|
36
|
+
it { expect(User.last.student? 'test/_').to be true }
|
37
|
+
it { expect(User.last.uid).to eq 'foo@bar.com' }
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
context 'post without permissions' do
|
42
|
+
before { post :create, params: {user: owner_json} }
|
43
|
+
|
44
|
+
it { expect(response.status).to eq 403 }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'put' do
|
48
|
+
before { User.create! user_json }
|
49
|
+
before { put :update, params: {id: 'foo@bar.com', user: {first_name: 'Fede'}} }
|
50
|
+
|
51
|
+
it { expect(response.status).to eq 200 }
|
52
|
+
it { expect(User.last.first_name).to eq('Fede') }
|
53
|
+
it { expect(User.last.uid).to eq 'foo@bar.com' }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|