scimitar 1.8.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/scimitar/active_record_backed_resources_controller.rb +20 -94
- data/app/controllers/scimitar/application_controller.rb +13 -41
- data/app/controllers/scimitar/schemas_controller.rb +0 -5
- data/app/models/scimitar/complex_types/address.rb +6 -0
- data/app/models/scimitar/engine_configuration.rb +5 -13
- data/app/models/scimitar/error_response.rb +0 -12
- data/app/models/scimitar/lists/query_parser.rb +10 -25
- data/app/models/scimitar/resource_invalid_error.rb +1 -1
- data/app/models/scimitar/resources/base.rb +4 -14
- data/app/models/scimitar/resources/mixin.rb +13 -140
- data/app/models/scimitar/schema/address.rb +0 -1
- data/app/models/scimitar/schema/attribute.rb +5 -14
- data/app/models/scimitar/schema/base.rb +1 -1
- data/app/models/scimitar/schema/vdtp.rb +1 -1
- data/app/models/scimitar/service_provider_configuration.rb +3 -14
- data/config/initializers/scimitar.rb +3 -28
- data/lib/scimitar/version.rb +2 -2
- data/lib/scimitar.rb +2 -7
- data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
- data/spec/apps/dummy/app/models/mock_group.rb +1 -1
- data/spec/apps/dummy/app/models/mock_user.rb +8 -36
- data/spec/apps/dummy/config/application.rb +1 -0
- data/spec/apps/dummy/config/environments/test.rb +28 -5
- data/spec/apps/dummy/config/initializers/scimitar.rb +10 -61
- data/spec/apps/dummy/config/routes.rb +7 -28
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -10
- data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
- data/spec/apps/dummy/db/schema.rb +4 -11
- data/spec/controllers/scimitar/application_controller_spec.rb +3 -126
- data/spec/controllers/scimitar/resource_types_controller_spec.rb +2 -2
- data/spec/controllers/scimitar/schemas_controller_spec.rb +2 -10
- data/spec/models/scimitar/complex_types/address_spec.rb +4 -3
- data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
- data/spec/models/scimitar/lists/query_parser_spec.rb +9 -76
- data/spec/models/scimitar/resources/base_spec.rb +70 -208
- data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
- data/spec/models/scimitar/resources/mixin_spec.rb +43 -790
- data/spec/models/scimitar/schema/attribute_spec.rb +3 -22
- data/spec/models/scimitar/schema/base_spec.rb +1 -1
- data/spec/models/scimitar/schema/user_spec.rb +0 -10
- data/spec/requests/active_record_backed_resources_controller_spec.rb +66 -709
- data/spec/requests/application_controller_spec.rb +3 -16
- data/spec/spec_helper.rb +0 -8
- metadata +14 -25
- data/LICENSE.txt +0 -21
- data/README.md +0 -710
- data/lib/scimitar/support/utilities.rb +0 -51
- data/spec/apps/dummy/app/controllers/custom_create_mock_users_controller.rb +0 -25
- data/spec/apps/dummy/app/controllers/custom_replace_mock_users_controller.rb +0 -25
- data/spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb +0 -24
- data/spec/apps/dummy/app/controllers/custom_update_mock_users_controller.rb +0 -25
@@ -1,24 +1,15 @@
|
|
1
1
|
class CreateMockUsers < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
|
-
create_table :mock_users
|
4
|
-
t.timestamps
|
3
|
+
create_table :mock_users do |t|
|
5
4
|
|
6
|
-
# Support part of the core schema
|
7
|
-
#
|
8
5
|
t.text :scim_uid
|
9
6
|
t.text :username
|
10
|
-
t.text :password
|
11
7
|
t.text :first_name
|
12
8
|
t.text :last_name
|
13
9
|
t.text :work_email_address
|
14
10
|
t.text :home_email_address
|
15
11
|
t.text :work_phone_number
|
16
12
|
|
17
|
-
# Support the custom extension schema - see configuration in
|
18
|
-
# "spec/apps/dummy/config/initializers/scimitar.rb".
|
19
|
-
#
|
20
|
-
t.text :organization
|
21
|
-
t.text :department
|
22
13
|
end
|
23
14
|
end
|
24
15
|
end
|
@@ -1,13 +1,8 @@
|
|
1
1
|
class CreateJoinTableMockGroupsMockUsers < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
|
-
|
4
|
-
t.
|
5
|
-
t.
|
6
|
-
|
7
|
-
# The 'foreign_key:' option (used above) only works for 'id' column names
|
8
|
-
# but the test data has a column named 'primary_key' for 'mock_users'.
|
9
|
-
#
|
10
|
-
t.foreign_key :mock_users, primary_key: :primary_key
|
3
|
+
create_join_table :mock_groups, :mock_users do |t|
|
4
|
+
t.index [:mock_group_id, :mock_user_id]
|
5
|
+
t.index [:mock_user_id, :mock_group_id]
|
11
6
|
end
|
12
7
|
end
|
13
8
|
end
|
@@ -24,26 +24,19 @@ ActiveRecord::Schema.define(version: 2021_03_08_044214) do
|
|
24
24
|
|
25
25
|
create_table "mock_groups_users", id: false, force: :cascade do |t|
|
26
26
|
t.bigint "mock_group_id", null: false
|
27
|
-
t.
|
28
|
-
t.index ["mock_group_id"], name: "
|
29
|
-
t.index ["mock_user_id"], name: "
|
27
|
+
t.bigint "mock_user_id", null: false
|
28
|
+
t.index ["mock_group_id", "mock_user_id"], name: "index_mock_groups_users_on_mock_group_id_and_mock_user_id"
|
29
|
+
t.index ["mock_user_id", "mock_group_id"], name: "index_mock_groups_users_on_mock_user_id_and_mock_group_id"
|
30
30
|
end
|
31
31
|
|
32
|
-
create_table "mock_users",
|
33
|
-
t.datetime "created_at", null: false
|
34
|
-
t.datetime "updated_at", null: false
|
32
|
+
create_table "mock_users", force: :cascade do |t|
|
35
33
|
t.text "scim_uid"
|
36
34
|
t.text "username"
|
37
|
-
t.text "password"
|
38
35
|
t.text "first_name"
|
39
36
|
t.text "last_name"
|
40
37
|
t.text "work_email_address"
|
41
38
|
t.text "home_email_address"
|
42
39
|
t.text "work_phone_number"
|
43
|
-
t.text "organization"
|
44
|
-
t.text "department"
|
45
40
|
end
|
46
41
|
|
47
|
-
add_foreign_key "mock_groups_users", "mock_groups"
|
48
|
-
add_foreign_key "mock_groups_users", "mock_users", primary_key: "primary_key"
|
49
42
|
end
|
@@ -24,7 +24,7 @@ RSpec.describe Scimitar::ApplicationController do
|
|
24
24
|
get :index, params: { format: :scim }
|
25
25
|
expect(response).to be_ok
|
26
26
|
expect(JSON.parse(response.body)).to eql({ 'message' => 'cool, cool!' })
|
27
|
-
expect(response.headers['
|
27
|
+
expect(response.headers['WWW_AUTHENTICATE']).to eql('Basic')
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'renders failure with bad password' do
|
@@ -84,61 +84,7 @@ RSpec.describe Scimitar::ApplicationController do
|
|
84
84
|
get :index, params: { format: :scim }
|
85
85
|
expect(response).to be_ok
|
86
86
|
expect(JSON.parse(response.body)).to eql({ 'message' => 'cool, cool!' })
|
87
|
-
expect(response.headers['
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'renders failure with bad token' do
|
91
|
-
request.env['HTTP_AUTHORIZATION'] = 'Bearer Invalid'
|
92
|
-
|
93
|
-
get :index, params: { format: :scim }
|
94
|
-
expect(response).not_to be_ok
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'renders failure with blank token' do
|
98
|
-
request.env['HTTP_AUTHORIZATION'] = 'Bearer'
|
99
|
-
|
100
|
-
get :index, params: { format: :scim }
|
101
|
-
expect(response).not_to be_ok
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'renders failure with missing header' do
|
105
|
-
get :index, params: { format: :scim }
|
106
|
-
expect(response).not_to be_ok
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
context 'authenticator evaluated within controller context' do
|
111
|
-
|
112
|
-
# Define a controller with a custom instance method 'valid_token'.
|
113
|
-
#
|
114
|
-
controller do
|
115
|
-
def index
|
116
|
-
render json: { 'message' => 'cool, cool!' }, format: :scim
|
117
|
-
end
|
118
|
-
|
119
|
-
def valid_token
|
120
|
-
'B'
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Call the above controller method from the token authenticator Proc,
|
125
|
-
# proving that it was executed in the controller's context.
|
126
|
-
#
|
127
|
-
before do
|
128
|
-
Scimitar.engine_configuration = Scimitar::EngineConfiguration.new(
|
129
|
-
token_authenticator: Proc.new do | token, options |
|
130
|
-
token == self.valid_token()
|
131
|
-
end
|
132
|
-
)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'renders success when valid creds are given' do
|
136
|
-
request.env['HTTP_AUTHORIZATION'] = 'Bearer B'
|
137
|
-
|
138
|
-
get :index, params: { format: :scim }
|
139
|
-
expect(response).to be_ok
|
140
|
-
expect(JSON.parse(response.body)).to eql({ 'message' => 'cool, cool!' })
|
141
|
-
expect(response.headers['WWW-Authenticate']).to eql('Bearer')
|
87
|
+
expect(response.headers['WWW_AUTHENTICATE']).to eql('Bearer')
|
142
88
|
end
|
143
89
|
|
144
90
|
it 'renders failure with bad token' do
|
@@ -223,74 +169,5 @@ RSpec.describe Scimitar::ApplicationController do
|
|
223
169
|
expect(parsed_body).to include('status' => '500')
|
224
170
|
expect(parsed_body).to include('detail' => 'Bang')
|
225
171
|
end
|
226
|
-
|
227
|
-
context 'with an exception reporter' do
|
228
|
-
around :each do | example |
|
229
|
-
original_configuration = Scimitar.engine_configuration.exception_reporter
|
230
|
-
Scimitar.engine_configuration.exception_reporter = Proc.new do | exception |
|
231
|
-
@exception = exception
|
232
|
-
end
|
233
|
-
example.run()
|
234
|
-
ensure
|
235
|
-
Scimitar.engine_configuration.exception_reporter = original_configuration
|
236
|
-
end
|
237
|
-
|
238
|
-
context 'and "internal server error"' do
|
239
|
-
it 'is invoked' do
|
240
|
-
get :index, params: { format: :scim }
|
241
|
-
|
242
|
-
expect(@exception).to be_a(RuntimeError)
|
243
|
-
expect(@exception.message).to eql('Bang')
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
context 'and "not found"' do
|
248
|
-
controller do
|
249
|
-
def index
|
250
|
-
handle_resource_not_found(ActiveRecord::RecordNotFound.new(42))
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
it 'is invoked' do
|
255
|
-
get :index, params: { format: :scim }
|
256
|
-
|
257
|
-
expect(@exception).to be_a(ActiveRecord::RecordNotFound)
|
258
|
-
expect(@exception.message).to eql('42')
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
context 'and bad JSON' do
|
263
|
-
controller do
|
264
|
-
def index
|
265
|
-
begin
|
266
|
-
raise 'Hello'
|
267
|
-
rescue
|
268
|
-
raise ActionDispatch::Http::Parameters::ParseError
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'is invoked' do
|
274
|
-
get :index, params: { format: :scim }
|
275
|
-
|
276
|
-
expect(@exception).to be_a(ActionDispatch::Http::Parameters::ParseError)
|
277
|
-
expect(@exception.message).to eql('Hello')
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
context 'and a bad content type' do
|
282
|
-
controller do
|
283
|
-
def index; end
|
284
|
-
end
|
285
|
-
|
286
|
-
it 'is invoked' do
|
287
|
-
request.headers['Content-Type'] = 'text/plain'
|
288
|
-
get :index
|
289
|
-
|
290
|
-
expect(@exception).to be_a(Scimitar::ErrorResponse)
|
291
|
-
expect(@exception.message).to eql('Only application/scim+json type is accepted.')
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end # "context 'exception reporter' do"
|
295
|
-
end # "context 'error handling' do"
|
172
|
+
end
|
296
173
|
end
|
@@ -9,8 +9,8 @@ RSpec.describe Scimitar::ResourceTypesController do
|
|
9
9
|
it 'renders the resource type for user' do
|
10
10
|
get :index, format: :scim
|
11
11
|
response_hash = JSON.parse(response.body)
|
12
|
-
expected_response = [ Scimitar::Resources::User.resource_type(scim_resource_type_url(name: 'User'
|
13
|
-
Scimitar::Resources::Group.resource_type(scim_resource_type_url(name: 'Group'
|
12
|
+
expected_response = [ Scimitar::Resources::User.resource_type(scim_resource_type_url(name: 'User')),
|
13
|
+
Scimitar::Resources::Group.resource_type(scim_resource_type_url(name: 'Group'))
|
14
14
|
].to_json
|
15
15
|
|
16
16
|
response_hash = JSON.parse(response.body)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Scimitar::SchemasController do
|
4
|
-
routes { Scimitar::Engine.routes }
|
5
4
|
|
6
5
|
before(:each) { allow(controller).to receive(:authenticated?).and_return(true) }
|
7
6
|
|
@@ -15,9 +14,9 @@ RSpec.describe Scimitar::SchemasController do
|
|
15
14
|
get :index, params: { format: :scim }
|
16
15
|
expect(response).to be_ok
|
17
16
|
parsed_body = JSON.parse(response.body)
|
18
|
-
expect(parsed_body.length).to eql(
|
17
|
+
expect(parsed_body.length).to eql(2)
|
19
18
|
schema_names = parsed_body.map {|schema| schema['name']}
|
20
|
-
expect(schema_names).to match_array(['User', '
|
19
|
+
expect(schema_names).to match_array(['User', 'Group'])
|
21
20
|
end
|
22
21
|
|
23
22
|
it 'returns only the User schema when its id is provided' do
|
@@ -27,13 +26,6 @@ RSpec.describe Scimitar::SchemasController do
|
|
27
26
|
expect(parsed_body['name']).to eql('User')
|
28
27
|
end
|
29
28
|
|
30
|
-
it 'includes the controller customised schema location' do
|
31
|
-
get :index, params: { name: Scimitar::Schema::User.id, format: :scim }
|
32
|
-
expect(response).to be_ok
|
33
|
-
parsed_body = JSON.parse(response.body)
|
34
|
-
expect(parsed_body.dig('meta', 'location')).to eq scim_schemas_url(name: Scimitar::Schema::User.id, test: 1)
|
35
|
-
end
|
36
|
-
|
37
29
|
it 'returns only the Group schema when its id is provided' do
|
38
30
|
get :index, params: { name: Scimitar::Schema::Group.id, format: :scim }
|
39
31
|
expect(response).to be_ok
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Scimitar::ComplexTypes::Address do
|
4
4
|
context '#as_json' do
|
5
|
-
it 'assumes
|
6
|
-
expect(described_class.new.as_json).to eq(
|
5
|
+
it 'assumes a type of "work" as a default' do
|
6
|
+
expect(described_class.new.as_json).to eq('type' => 'work')
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'allows a custom address type' do
|
@@ -11,8 +11,9 @@ RSpec.describe Scimitar::ComplexTypes::Address do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'shows the set address' do
|
14
|
-
expect(described_class.new(country: 'NZ').as_json).to eq('country' => 'NZ')
|
14
|
+
expect(described_class.new(country: 'NZ').as_json).to eq('type' => 'work', 'country' => 'NZ')
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
19
|
+
|
@@ -405,19 +405,19 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
405
405
|
query = @instance.to_activerecord_query(MockUser.all)
|
406
406
|
|
407
407
|
expect(query.count).to eql(1)
|
408
|
-
expect(query.pluck(:
|
408
|
+
expect(query.pluck(:id)).to eql([user_1.id])
|
409
409
|
|
410
410
|
@instance.parse('name.givenName sw J') # First name starts with 'J'
|
411
411
|
query = @instance.to_activerecord_query(MockUser.all)
|
412
412
|
|
413
413
|
expect(query.count).to eql(2)
|
414
|
-
expect(query.pluck(:
|
414
|
+
expect(query.pluck(:id)).to match_array([user_1.id, user_2.id])
|
415
415
|
|
416
416
|
@instance.parse('name.familyName ew he') # Last name ends with 'he'
|
417
417
|
query = @instance.to_activerecord_query(MockUser.all)
|
418
418
|
|
419
419
|
expect(query.count).to eql(1)
|
420
|
-
expect(query.pluck(:
|
420
|
+
expect(query.pluck(:id)).to eql([user_2.id])
|
421
421
|
|
422
422
|
# Test presence
|
423
423
|
|
@@ -425,7 +425,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
425
425
|
query = @instance.to_activerecord_query(MockUser.all)
|
426
426
|
|
427
427
|
expect(query.count).to eql(2)
|
428
|
-
expect(query.pluck(:
|
428
|
+
expect(query.pluck(:id)).to match_array([user_1.id, user_2.id])
|
429
429
|
|
430
430
|
# Test a simple not-equals, but use a custom starting scope. Note that
|
431
431
|
# the query would find "user_3" *except* there is no first name defined
|
@@ -435,7 +435,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
435
435
|
query = @instance.to_activerecord_query(MockUser.where.not('first_name' => 'John'))
|
436
436
|
|
437
437
|
expect(query.count).to eql(1)
|
438
|
-
expect(query.pluck(:
|
438
|
+
expect(query.pluck(:id)).to match_array([user_1.id])
|
439
439
|
end
|
440
440
|
|
441
441
|
context 'when mapped to multiple columns' do
|
@@ -481,66 +481,6 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
481
481
|
end
|
482
482
|
end # "context 'when instructed to ignore an attribute' do"
|
483
483
|
|
484
|
-
context 'when an arel column is mapped' do
|
485
|
-
let(:scope_with_groups) { MockUser.left_joins(:mock_groups) }
|
486
|
-
|
487
|
-
context 'with binary operators' do
|
488
|
-
it 'reads across all using OR' do
|
489
|
-
@instance.parse('groups eq "12345"')
|
490
|
-
query = @instance.to_activerecord_query(scope_with_groups)
|
491
|
-
|
492
|
-
expect(query.to_sql).to eql(<<~SQL.squish)
|
493
|
-
SELECT "mock_users".*
|
494
|
-
FROM "mock_users"
|
495
|
-
LEFT OUTER JOIN "mock_groups_users" ON "mock_groups_users"."mock_user_id" = "mock_users"."primary_key"
|
496
|
-
LEFT OUTER JOIN "mock_groups" ON "mock_groups"."id" = "mock_groups_users"."mock_group_id"
|
497
|
-
WHERE "mock_groups"."id" ILIKE 12345
|
498
|
-
SQL
|
499
|
-
end
|
500
|
-
|
501
|
-
it 'works with other query elements using correct precedence' do
|
502
|
-
@instance.parse('groups eq "12345" and emails eq "any@test.com"')
|
503
|
-
query = @instance.to_activerecord_query(scope_with_groups)
|
504
|
-
|
505
|
-
expect(query.to_sql).to eql(<<~SQL.squish)
|
506
|
-
SELECT "mock_users".*
|
507
|
-
FROM "mock_users"
|
508
|
-
LEFT OUTER JOIN "mock_groups_users" ON "mock_groups_users"."mock_user_id" = "mock_users"."primary_key"
|
509
|
-
LEFT OUTER JOIN "mock_groups" ON "mock_groups"."id" = "mock_groups_users"."mock_group_id"
|
510
|
-
WHERE "mock_groups"."id" ILIKE 12345 AND ("mock_users"."work_email_address" ILIKE 'any@test.com' OR "mock_users"."home_email_address" ILIKE 'any@test.com')
|
511
|
-
SQL
|
512
|
-
end
|
513
|
-
end # "context 'with binary operators' do"
|
514
|
-
|
515
|
-
context 'with unary operators' do
|
516
|
-
it 'reads across all using OR' do
|
517
|
-
@instance.parse('groups pr')
|
518
|
-
query = @instance.to_activerecord_query(scope_with_groups)
|
519
|
-
|
520
|
-
expect(query.to_sql).to eql(<<~SQL.squish)
|
521
|
-
SELECT "mock_users".*
|
522
|
-
FROM "mock_users"
|
523
|
-
LEFT OUTER JOIN "mock_groups_users" ON "mock_groups_users"."mock_user_id" = "mock_users"."primary_key"
|
524
|
-
LEFT OUTER JOIN "mock_groups" ON "mock_groups"."id" = "mock_groups_users"."mock_group_id"
|
525
|
-
WHERE ("mock_groups"."id" != NULL AND "mock_groups"."id" IS NOT NULL)
|
526
|
-
SQL
|
527
|
-
end
|
528
|
-
|
529
|
-
it 'works with other query elements using correct precedence' do
|
530
|
-
@instance.parse('name.familyName eq "John" and groups pr')
|
531
|
-
query = @instance.to_activerecord_query(scope_with_groups)
|
532
|
-
|
533
|
-
expect(query.to_sql).to eql(<<~SQL.squish)
|
534
|
-
SELECT "mock_users".*
|
535
|
-
FROM "mock_users"
|
536
|
-
LEFT OUTER JOIN "mock_groups_users" ON "mock_groups_users"."mock_user_id" = "mock_users"."primary_key"
|
537
|
-
LEFT OUTER JOIN "mock_groups" ON "mock_groups"."id" = "mock_groups_users"."mock_group_id"
|
538
|
-
WHERE "mock_users"."last_name" ILIKE 'John' AND ("mock_groups"."id" != NULL AND "mock_groups"."id" IS NOT NULL)
|
539
|
-
SQL
|
540
|
-
end
|
541
|
-
end # "context 'with unary operators' do
|
542
|
-
end # "context 'when an arel column is mapped' do"
|
543
|
-
|
544
484
|
context 'with complex cases' do
|
545
485
|
context 'using AND' do
|
546
486
|
it 'generates expected SQL' do
|
@@ -559,7 +499,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
559
499
|
query = @instance.to_activerecord_query(MockUser.all)
|
560
500
|
|
561
501
|
expect(query.count).to eql(1)
|
562
|
-
expect(query.pluck(:
|
502
|
+
expect(query.pluck(:id)).to match_array([user_2.id])
|
563
503
|
end
|
564
504
|
end # "context 'simple AND' do"
|
565
505
|
|
@@ -580,7 +520,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
580
520
|
query = @instance.to_activerecord_query(MockUser.all)
|
581
521
|
|
582
522
|
expect(query.count).to eql(2)
|
583
|
-
expect(query.pluck(:
|
523
|
+
expect(query.pluck(:id)).to match_array([user_1.id, user_2.id])
|
584
524
|
end
|
585
525
|
end # "context 'simple OR' do"
|
586
526
|
|
@@ -592,13 +532,6 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
592
532
|
expect(query.to_sql).to eql(%q{SELECT "mock_users".* FROM "mock_users" WHERE "mock_users"."first_name" ILIKE 'Jane' AND ("mock_users"."last_name" ILIKE '%avi%' OR "mock_users"."last_name" ILIKE '%ith')})
|
593
533
|
end
|
594
534
|
|
595
|
-
it 'combined parentheses generates expected SQL' do
|
596
|
-
@instance.parse('(name.givenName eq "Jane" OR name.givenName eq "Jaden") and (name.familyName co "avi" or name.familyName ew "ith")')
|
597
|
-
query = @instance.to_activerecord_query(MockUser.all)
|
598
|
-
|
599
|
-
expect(query.to_sql).to eql(%q{SELECT "mock_users".* FROM "mock_users" WHERE ("mock_users"."first_name" ILIKE 'Jane' OR "mock_users"."first_name" ILIKE 'Jaden') AND ("mock_users"."last_name" ILIKE '%avi%' OR "mock_users"."last_name" ILIKE '%ith')})
|
600
|
-
end
|
601
|
-
|
602
535
|
it 'finds expected items' do
|
603
536
|
user_1 = MockUser.create(username: '1', first_name: 'Jane', last_name: 'Davis') # Match
|
604
537
|
user_2 = MockUser.create(username: '2', first_name: 'Jane', last_name: 'Smith') # Match
|
@@ -613,7 +546,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
613
546
|
query = @instance.to_activerecord_query(MockUser.all)
|
614
547
|
|
615
548
|
expect(query.count).to eql(3)
|
616
|
-
expect(query.pluck(:
|
549
|
+
expect(query.pluck(:id)).to match_array([user_1.id, user_2.id, user_3.id])
|
617
550
|
end
|
618
551
|
end # "context 'combined AND and OR' do"
|
619
552
|
|
@@ -657,7 +590,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
657
590
|
end
|
658
591
|
|
659
592
|
it 'complains if there is no column mapping available' do
|
660
|
-
expect { @instance.send(:activerecord_columns, '
|
593
|
+
expect { @instance.send(:activerecord_columns, 'externalId') }.to raise_error(Scimitar::FilterError)
|
661
594
|
end
|
662
595
|
|
663
596
|
it 'complains about malformed declarations' do
|