scimitar 1.5.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/app/controllers/scimitar/active_record_backed_resources_controller.rb +6 -27
 - data/app/controllers/scimitar/application_controller.rb +9 -29
 - data/app/models/scimitar/engine_configuration.rb +3 -7
 - data/app/models/scimitar/error_response.rb +0 -12
 - data/app/models/scimitar/errors.rb +1 -1
 - data/app/models/scimitar/lists/query_parser.rb +4 -14
 - data/app/models/scimitar/resources/base.rb +1 -1
 - data/app/models/scimitar/resources/mixin.rb +4 -113
 - data/app/models/scimitar/schema/address.rb +0 -1
 - data/app/models/scimitar/schema/attribute.rb +1 -1
 - data/app/models/scimitar/schema/base.rb +3 -1
 - data/app/models/scimitar/schema/vdtp.rb +1 -1
 - data/config/initializers/scimitar.rb +70 -86
 - data/lib/scimitar/version.rb +2 -2
 - 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 -19
 - 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 +9 -44
 - data/spec/apps/dummy/config/routes.rb +0 -4
 - data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -9
 - 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 -10
 - data/spec/controllers/scimitar/application_controller_spec.rb +1 -70
 - data/spec/controllers/scimitar/schemas_controller_spec.rb +2 -2
 - data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
 - data/spec/models/scimitar/lists/query_parser_spec.rb +9 -9
 - data/spec/models/scimitar/resources/base_spec.rb +66 -161
 - data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
 - data/spec/models/scimitar/resources/mixin_spec.rb +43 -757
 - data/spec/models/scimitar/resources/user_spec.rb +4 -4
 - data/spec/models/scimitar/schema/attribute_spec.rb +3 -0
 - 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 +40 -309
 - data/spec/requests/application_controller_spec.rb +3 -17
 - metadata +7 -7
 
    
        data/lib/scimitar/version.rb
    CHANGED
    
    | 
         @@ -3,11 +3,11 @@ module Scimitar 
     | 
|
| 
       3 
3 
     | 
    
         
             
              # Gem version. If this changes, be sure to re-run "bundle install" or
         
     | 
| 
       4 
4 
     | 
    
         
             
              # "bundle update".
         
     | 
| 
       5 
5 
     | 
    
         
             
              #
         
     | 
| 
       6 
     | 
    
         
            -
              VERSION = ' 
     | 
| 
      
 6 
     | 
    
         
            +
              VERSION = '2.0.0'
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
              # Date for VERSION. If this changes, be sure to re-run "bundle install"
         
     | 
| 
       9 
9 
     | 
    
         
             
              # or "bundle update".
         
     | 
| 
       10 
10 
     | 
    
         
             
              #
         
     | 
| 
       11 
     | 
    
         
            -
              DATE = ' 
     | 
| 
      
 11 
     | 
    
         
            +
              DATE = '2022-03-04'
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            end
         
     | 
| 
         @@ -5,7 +5,7 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       5 
5 
     | 
    
         
             
              # ===========================================================================
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
              READWRITE_ATTRS = %w{
         
     | 
| 
       8 
     | 
    
         
            -
                 
     | 
| 
      
 8 
     | 
    
         
            +
                id
         
     | 
| 
       9 
9 
     | 
    
         
             
                scim_uid
         
     | 
| 
       10 
10 
     | 
    
         
             
                username
         
     | 
| 
       11 
11 
     | 
    
         
             
                first_name
         
     | 
| 
         @@ -13,8 +13,6 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       13 
13 
     | 
    
         
             
                work_email_address
         
     | 
| 
       14 
14 
     | 
    
         
             
                home_email_address
         
     | 
| 
       15 
15 
     | 
    
         
             
                work_phone_number
         
     | 
| 
       16 
     | 
    
         
            -
                organization
         
     | 
| 
       17 
     | 
    
         
            -
                department
         
     | 
| 
       18 
16 
     | 
    
         
             
              }
         
     | 
| 
       19 
17 
     | 
    
         | 
| 
       20 
18 
     | 
    
         
             
              has_and_belongs_to_many :mock_groups
         
     | 
| 
         @@ -40,7 +38,7 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       40 
38 
     | 
    
         | 
| 
       41 
39 
     | 
    
         
             
              def self.scim_attributes_map
         
     | 
| 
       42 
40 
     | 
    
         
             
                return {
         
     | 
| 
       43 
     | 
    
         
            -
                  id:         : 
     | 
| 
      
 41 
     | 
    
         
            +
                  id:         :id,
         
     | 
| 
       44 
42 
     | 
    
         
             
                  externalId: :scim_uid,
         
     | 
| 
       45 
43 
     | 
    
         
             
                  userName:   :username,
         
     | 
| 
       46 
44 
     | 
    
         
             
                  name:       {
         
     | 
| 
         @@ -84,13 +82,7 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       84 
82 
     | 
    
         
             
                      }
         
     | 
| 
       85 
83 
     | 
    
         
             
                    }
         
     | 
| 
       86 
84 
     | 
    
         
             
                  ],
         
     | 
| 
       87 
     | 
    
         
            -
                  active: :is_active 
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                  # Custom extension schema - see configuration in
         
     | 
| 
       90 
     | 
    
         
            -
                  # "spec/apps/dummy/config/initializers/scimitar.rb".
         
     | 
| 
       91 
     | 
    
         
            -
                  #
         
     | 
| 
       92 
     | 
    
         
            -
                  organization: :organization,
         
     | 
| 
       93 
     | 
    
         
            -
                  department:   :department
         
     | 
| 
      
 85 
     | 
    
         
            +
                  active: :is_active
         
     | 
| 
       94 
86 
     | 
    
         
             
                }
         
     | 
| 
       95 
87 
     | 
    
         
             
              end
         
     | 
| 
       96 
88 
     | 
    
         | 
| 
         @@ -100,14 +92,11 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       100 
92 
     | 
    
         | 
| 
       101 
93 
     | 
    
         
             
              def self.scim_queryable_attributes
         
     | 
| 
       102 
94 
     | 
    
         
             
                return {
         
     | 
| 
       103 
     | 
    
         
            -
                  ' 
     | 
| 
       104 
     | 
    
         
            -
                  ' 
     | 
| 
       105 
     | 
    
         
            -
                  ' 
     | 
| 
       106 
     | 
    
         
            -
                  ' 
     | 
| 
       107 
     | 
    
         
            -
                  ' 
     | 
| 
       108 
     | 
    
         
            -
                  'emails'            => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
       109 
     | 
    
         
            -
                  'emails.value'      => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
       110 
     | 
    
         
            -
                  'emails.type'       => { ignore: true } # We can't filter on that; it'll just search all e-mails
         
     | 
| 
      
 95 
     | 
    
         
            +
                  'name.givenName'  => { column: :first_name },
         
     | 
| 
      
 96 
     | 
    
         
            +
                  'name.familyName' => { column: :last_name  },
         
     | 
| 
      
 97 
     | 
    
         
            +
                  'emails'          => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
      
 98 
     | 
    
         
            +
                  'emails.value'    => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
      
 99 
     | 
    
         
            +
                  'emails.type'     => { ignore: true } # We can't filter on that; it'll just search all e-mails
         
     | 
| 
       111 
100 
     | 
    
         
             
                }
         
     | 
| 
       112 
101 
     | 
    
         
             
              end
         
     | 
| 
       113 
102 
     | 
    
         | 
| 
         @@ -1,15 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/integer/time'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            Rails.application.configure do
         
     | 
| 
       2 
4 
     | 
    
         
             
              config.cache_classes = true
         
     | 
| 
       3 
5 
     | 
    
         
             
              config.eager_load = false
         
     | 
| 
       4 
     | 
    
         
            -
              config.serve_static_files = true
         
     | 
| 
       5 
     | 
    
         
            -
              config.static_cache_control = 'public, max-age=3600'
         
     | 
| 
       6 
     | 
    
         
            -
              config.consider_all_requests_local = true
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
               
     | 
| 
      
 7 
     | 
    
         
            +
              # Configure public file server for tests with Cache-Control for performance.
         
     | 
| 
      
 8 
     | 
    
         
            +
              config.public_file_server.enabled = true
         
     | 
| 
      
 9 
     | 
    
         
            +
              config.public_file_server.headers = {
         
     | 
| 
      
 10 
     | 
    
         
            +
                'Cache-Control' => "public, max-age=#{1.hour.to_i}"
         
     | 
| 
      
 11 
     | 
    
         
            +
              }
         
     | 
| 
       9 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
              # Show full error reports and disable caching.
         
     | 
| 
      
 14 
     | 
    
         
            +
              config.consider_all_requests_local       = true
         
     | 
| 
       10 
15 
     | 
    
         
             
              config.action_controller.perform_caching = false
         
     | 
| 
      
 16 
     | 
    
         
            +
              config.cache_store = :null_store
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              # Raise exceptions instead of rendering exception templates.
         
     | 
| 
      
 19 
     | 
    
         
            +
              config.action_dispatch.show_exceptions = false
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              # Disable request forgery protection in test environment.
         
     | 
| 
       11 
22 
     | 
    
         
             
              config.action_controller.allow_forgery_protection = false
         
     | 
| 
       12 
23 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
               
     | 
| 
      
 24 
     | 
    
         
            +
              # Print deprecation notices to the stderr.
         
     | 
| 
       14 
25 
     | 
    
         
             
              config.active_support.deprecation = :stderr
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              # Raise exceptions for disallowed deprecations.
         
     | 
| 
      
 28 
     | 
    
         
            +
              config.active_support.disallowed_deprecation = :raise
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              # Tell Active Support which deprecation messages to disallow.
         
     | 
| 
      
 31 
     | 
    
         
            +
              config.active_support.disallowed_deprecation_warnings = []
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              # Raises error for missing translations.
         
     | 
| 
      
 34 
     | 
    
         
            +
              config.i18n.raise_on_missing_translations = true
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              # Annotate rendered view with file names.
         
     | 
| 
      
 37 
     | 
    
         
            +
              # config.action_view.annotate_rendered_view_with_filenames = true
         
     | 
| 
       15 
38 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,51 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Test app configuration.
         
     | 
| 
       2 
2 
     | 
    
         
             
            #
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            # some of the code from which Scimitar was originally built is that those
         
     | 
| 
       6 
     | 
    
         
            -
            # extensions are done with class-level ivars, so it is largely impossible (or
         
     | 
| 
       7 
     | 
    
         
            -
            # at least, impractical in tests) to avoid polluting the core class itself
         
     | 
| 
       8 
     | 
    
         
            -
            # with the extension.
         
     | 
| 
       9 
     | 
    
         
            -
            #
         
     | 
| 
       10 
     | 
    
         
            -
            # All related schema tests are written with this in mind.
         
     | 
| 
       11 
     | 
    
         
            -
            #
         
     | 
| 
       12 
     | 
    
         
            -
            Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
         
     | 
| 
      
 3 
     | 
    
         
            +
            Rails.application.config.to_prepare do
         
     | 
| 
      
 4 
     | 
    
         
            +
              Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
         
     | 
| 
       13 
5 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
                application_controller_mixin: Module.new do
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def self.included(base)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    base.class_eval do
         
     | 
| 
      
 9 
     | 
    
         
            +
                      def test_hook; end
         
     | 
| 
      
 10 
     | 
    
         
            +
                      before_action :test_hook
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
       19 
12 
     | 
    
         
             
                  end
         
     | 
| 
       20 
13 
     | 
    
         
             
                end
         
     | 
| 
       21 
     | 
    
         
            -
              end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            })
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            module ScimSchemaExtensions
         
     | 
| 
       26 
     | 
    
         
            -
              module User
         
     | 
| 
       27 
     | 
    
         
            -
                class Enterprise < Scimitar::Schema::Base
         
     | 
| 
       28 
     | 
    
         
            -
                  def initialize(options = {})
         
     | 
| 
       29 
     | 
    
         
            -
                    super(
         
     | 
| 
       30 
     | 
    
         
            -
                      name:            'ExtendedUser',
         
     | 
| 
       31 
     | 
    
         
            -
                      description:     'Enterprise extension for a User',
         
     | 
| 
       32 
     | 
    
         
            -
                      id:              self.class.id,
         
     | 
| 
       33 
     | 
    
         
            -
                      scim_attributes: self.class.scim_attributes
         
     | 
| 
       34 
     | 
    
         
            -
                    )
         
     | 
| 
       35 
     | 
    
         
            -
                  end
         
     | 
| 
       36 
14 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                    'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                  def self.scim_attributes
         
     | 
| 
       42 
     | 
    
         
            -
                    [
         
     | 
| 
       43 
     | 
    
         
            -
                      Scimitar::Schema::Attribute.new(name: 'organization', type: 'string'),
         
     | 
| 
       44 
     | 
    
         
            -
                      Scimitar::Schema::Attribute.new(name: 'department',   type: 'string')
         
     | 
| 
       45 
     | 
    
         
            -
                    ]
         
     | 
| 
       46 
     | 
    
         
            -
                  end
         
     | 
| 
       47 
     | 
    
         
            -
                end
         
     | 
| 
       48 
     | 
    
         
            -
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              })
         
     | 
| 
       49 
16 
     | 
    
         
             
            end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
            Scimitar::Resources::User.extend_schema ScimSchemaExtensions::User::Enterprise
         
     | 
| 
         @@ -13,10 +13,6 @@ Rails.application.routes.draw do 
     | 
|
| 
       13 
13 
     | 
    
         
             
              patch  'Users/:id', to: 'mock_users#update'
         
     | 
| 
       14 
14 
     | 
    
         
             
              delete 'Users/:id', to: 'mock_users#destroy'
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
              get    'Groups',     to: 'mock_groups#index'
         
     | 
| 
       17 
     | 
    
         
            -
              get    'Groups/:id', to: 'mock_groups#show'
         
     | 
| 
       18 
     | 
    
         
            -
              patch  'Groups/:id', to: 'mock_groups#update'
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
16 
     | 
    
         
             
              # For testing blocks passed to ActiveRecordBackedResourcesController#destroy
         
     | 
| 
       21 
17 
     | 
    
         
             
              #
         
     | 
| 
       22 
18 
     | 
    
         
             
              delete 'CustomDestroyUsers/:id', to: 'custom_destroy_mock_users#destroy'
         
     | 
| 
         @@ -1,10 +1,7 @@ 
     | 
|
| 
       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 
7 
     | 
    
         
             
                  t.text :first_name
         
     | 
| 
         @@ -13,11 +10,6 @@ class CreateMockUsers < ActiveRecord::Migration[6.1] 
     | 
|
| 
       13 
10 
     | 
    
         
             
                  t.text :home_email_address
         
     | 
| 
       14 
11 
     | 
    
         
             
                  t.text :work_phone_number
         
     | 
| 
       15 
12 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  # Support the custom extension schema - see configuration in
         
     | 
| 
       17 
     | 
    
         
            -
                  # "spec/apps/dummy/config/initializers/scimitar.rb".
         
     | 
| 
       18 
     | 
    
         
            -
                  #
         
     | 
| 
       19 
     | 
    
         
            -
                  t.text :organization
         
     | 
| 
       20 
     | 
    
         
            -
                  t.text :department
         
     | 
| 
       21 
13 
     | 
    
         
             
                end
         
     | 
| 
       22 
14 
     | 
    
         
             
              end
         
     | 
| 
       23 
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,14 +24,12 @@ 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", precision: 6, null: false
         
     | 
| 
       34 
     | 
    
         
            -
                t.datetime "updated_at", precision: 6, null: false
         
     | 
| 
      
 32 
     | 
    
         
            +
              create_table "mock_users", force: :cascade do |t|
         
     | 
| 
       35 
33 
     | 
    
         
             
                t.text "scim_uid"
         
     | 
| 
       36 
34 
     | 
    
         
             
                t.text "username"
         
     | 
| 
       37 
35 
     | 
    
         
             
                t.text "first_name"
         
     | 
| 
         @@ -39,10 +37,6 @@ ActiveRecord::Schema.define(version: 2021_03_08_044214) do 
     | 
|
| 
       39 
37 
     | 
    
         
             
                t.text "work_email_address"
         
     | 
| 
       40 
38 
     | 
    
         
             
                t.text "home_email_address"
         
     | 
| 
       41 
39 
     | 
    
         
             
                t.text "work_phone_number"
         
     | 
| 
       42 
     | 
    
         
            -
                t.text "organization"
         
     | 
| 
       43 
     | 
    
         
            -
                t.text "department"
         
     | 
| 
       44 
40 
     | 
    
         
             
              end
         
     | 
| 
       45 
41 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
              add_foreign_key "mock_groups_users", "mock_groups"
         
     | 
| 
       47 
     | 
    
         
            -
              add_foreign_key "mock_groups_users", "mock_users", primary_key: "primary_key"
         
     | 
| 
       48 
42 
     | 
    
         
             
            end
         
     | 
| 
         @@ -169,74 +169,5 @@ RSpec.describe Scimitar::ApplicationController do 
     | 
|
| 
       169 
169 
     | 
    
         
             
                  expect(parsed_body).to include('status' => '500')
         
     | 
| 
       170 
170 
     | 
    
         
             
                  expect(parsed_body).to include('detail' => 'Bang')
         
     | 
| 
       171 
171 
     | 
    
         
             
                end
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
                context 'with an exception reporter' do
         
     | 
| 
       174 
     | 
    
         
            -
                  around :each do | example |
         
     | 
| 
       175 
     | 
    
         
            -
                    original_configuration = Scimitar.engine_configuration.exception_reporter
         
     | 
| 
       176 
     | 
    
         
            -
                    Scimitar.engine_configuration.exception_reporter = Proc.new do | exception |
         
     | 
| 
       177 
     | 
    
         
            -
                      @exception = exception
         
     | 
| 
       178 
     | 
    
         
            -
                    end
         
     | 
| 
       179 
     | 
    
         
            -
                    example.run()
         
     | 
| 
       180 
     | 
    
         
            -
                  ensure
         
     | 
| 
       181 
     | 
    
         
            -
                    Scimitar.engine_configuration.exception_reporter = original_configuration
         
     | 
| 
       182 
     | 
    
         
            -
                  end
         
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
                  context 'and "internal server error"' do
         
     | 
| 
       185 
     | 
    
         
            -
                    it 'is invoked' do
         
     | 
| 
       186 
     | 
    
         
            -
                      get :index, params: { format: :scim }
         
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
                      expect(@exception).to be_a(RuntimeError)
         
     | 
| 
       189 
     | 
    
         
            -
                      expect(@exception.message).to eql('Bang')
         
     | 
| 
       190 
     | 
    
         
            -
                    end
         
     | 
| 
       191 
     | 
    
         
            -
                  end
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                  context 'and "not found"' do
         
     | 
| 
       194 
     | 
    
         
            -
                    controller do
         
     | 
| 
       195 
     | 
    
         
            -
                      def index
         
     | 
| 
       196 
     | 
    
         
            -
                        handle_resource_not_found(ActiveRecord::RecordNotFound.new(42))
         
     | 
| 
       197 
     | 
    
         
            -
                      end
         
     | 
| 
       198 
     | 
    
         
            -
                    end
         
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                    it 'is invoked' do
         
     | 
| 
       201 
     | 
    
         
            -
                      get :index, params: { format: :scim }
         
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
                      expect(@exception).to be_a(ActiveRecord::RecordNotFound)
         
     | 
| 
       204 
     | 
    
         
            -
                      expect(@exception.message).to eql('42')
         
     | 
| 
       205 
     | 
    
         
            -
                    end
         
     | 
| 
       206 
     | 
    
         
            -
                  end
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
                  context 'and bad JSON' do
         
     | 
| 
       209 
     | 
    
         
            -
                    controller do
         
     | 
| 
       210 
     | 
    
         
            -
                      def index
         
     | 
| 
       211 
     | 
    
         
            -
                        begin
         
     | 
| 
       212 
     | 
    
         
            -
                          raise 'Hello'
         
     | 
| 
       213 
     | 
    
         
            -
                        rescue
         
     | 
| 
       214 
     | 
    
         
            -
                          raise ActionDispatch::Http::Parameters::ParseError
         
     | 
| 
       215 
     | 
    
         
            -
                        end
         
     | 
| 
       216 
     | 
    
         
            -
                      end
         
     | 
| 
       217 
     | 
    
         
            -
                    end
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                    it 'is invoked' do
         
     | 
| 
       220 
     | 
    
         
            -
                      get :index, params: { format: :scim }
         
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
                      expect(@exception).to be_a(ActionDispatch::Http::Parameters::ParseError)
         
     | 
| 
       223 
     | 
    
         
            -
                      expect(@exception.message).to eql('Hello')
         
     | 
| 
       224 
     | 
    
         
            -
                    end
         
     | 
| 
       225 
     | 
    
         
            -
                  end
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
     | 
    
         
            -
                  context 'and a bad content type' do
         
     | 
| 
       228 
     | 
    
         
            -
                    controller do
         
     | 
| 
       229 
     | 
    
         
            -
                      def index; end
         
     | 
| 
       230 
     | 
    
         
            -
                    end
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
       232 
     | 
    
         
            -
                    it 'is invoked' do
         
     | 
| 
       233 
     | 
    
         
            -
                      request.headers['Content-Type'] = 'text/plain'
         
     | 
| 
       234 
     | 
    
         
            -
                      get :index
         
     | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
                      expect(@exception).to be_a(Scimitar::ErrorResponse)
         
     | 
| 
       237 
     | 
    
         
            -
                      expect(@exception.message).to eql('Only application/scim+json type is accepted.')
         
     | 
| 
       238 
     | 
    
         
            -
                    end
         
     | 
| 
       239 
     | 
    
         
            -
                  end
         
     | 
| 
       240 
     | 
    
         
            -
                end # "context 'exception reporter' do"
         
     | 
| 
       241 
     | 
    
         
            -
              end # "context 'error handling' do"
         
     | 
| 
      
 172 
     | 
    
         
            +
              end
         
     | 
| 
       242 
173 
     | 
    
         
             
            end
         
     | 
| 
         @@ -14,9 +14,9 @@ RSpec.describe Scimitar::SchemasController do 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  get :index, params: { format: :scim }
         
     | 
| 
       15 
15 
     | 
    
         
             
                  expect(response).to be_ok
         
     | 
| 
       16 
16 
     | 
    
         
             
                  parsed_body = JSON.parse(response.body)
         
     | 
| 
       17 
     | 
    
         
            -
                  expect(parsed_body.length).to eql( 
     | 
| 
      
 17 
     | 
    
         
            +
                  expect(parsed_body.length).to eql(2)
         
     | 
| 
       18 
18 
     | 
    
         
             
                  schema_names = parsed_body.map {|schema| schema['name']}
         
     | 
| 
       19 
     | 
    
         
            -
                  expect(schema_names).to match_array(['User', ' 
     | 
| 
      
 19 
     | 
    
         
            +
                  expect(schema_names).to match_array(['User', 'Group'])
         
     | 
| 
       20 
20 
     | 
    
         
             
                end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                it 'returns only the User schema when its id is provided' do
         
     | 
| 
         @@ -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
         
     | 
| 
         @@ -499,7 +499,7 @@ RSpec.describe Scimitar::Lists::QueryParser do 
     | 
|
| 
       499 
499 
     | 
    
         
             
                      query = @instance.to_activerecord_query(MockUser.all)
         
     | 
| 
       500 
500 
     | 
    
         | 
| 
       501 
501 
     | 
    
         
             
                      expect(query.count).to eql(1)
         
     | 
| 
       502 
     | 
    
         
            -
                      expect(query.pluck(: 
     | 
| 
      
 502 
     | 
    
         
            +
                      expect(query.pluck(:id)).to match_array([user_2.id])
         
     | 
| 
       503 
503 
     | 
    
         
             
                    end
         
     | 
| 
       504 
504 
     | 
    
         
             
                  end # "context 'simple AND' do"
         
     | 
| 
       505 
505 
     | 
    
         | 
| 
         @@ -520,7 +520,7 @@ RSpec.describe Scimitar::Lists::QueryParser do 
     | 
|
| 
       520 
520 
     | 
    
         
             
                      query = @instance.to_activerecord_query(MockUser.all)
         
     | 
| 
       521 
521 
     | 
    
         | 
| 
       522 
522 
     | 
    
         
             
                      expect(query.count).to eql(2)
         
     | 
| 
       523 
     | 
    
         
            -
                      expect(query.pluck(: 
     | 
| 
      
 523 
     | 
    
         
            +
                      expect(query.pluck(:id)).to match_array([user_1.id, user_2.id])
         
     | 
| 
       524 
524 
     | 
    
         
             
                    end
         
     | 
| 
       525 
525 
     | 
    
         
             
                  end # "context 'simple OR' do"
         
     | 
| 
       526 
526 
     | 
    
         | 
| 
         @@ -546,7 +546,7 @@ RSpec.describe Scimitar::Lists::QueryParser do 
     | 
|
| 
       546 
546 
     | 
    
         
             
                      query = @instance.to_activerecord_query(MockUser.all)
         
     | 
| 
       547 
547 
     | 
    
         | 
| 
       548 
548 
     | 
    
         
             
                      expect(query.count).to eql(3)
         
     | 
| 
       549 
     | 
    
         
            -
                      expect(query.pluck(: 
     | 
| 
      
 549 
     | 
    
         
            +
                      expect(query.pluck(:id)).to match_array([user_1.id, user_2.id, user_3.id])
         
     | 
| 
       550 
550 
     | 
    
         
             
                    end
         
     | 
| 
       551 
551 
     | 
    
         
             
                  end # "context 'combined AND and OR' do"
         
     | 
| 
       552 
552 
     | 
    
         | 
| 
         @@ -590,7 +590,7 @@ RSpec.describe Scimitar::Lists::QueryParser do 
     | 
|
| 
       590 
590 
     | 
    
         
             
                  end
         
     | 
| 
       591 
591 
     | 
    
         | 
| 
       592 
592 
     | 
    
         
             
                  it 'complains if there is no column mapping available' do
         
     | 
| 
       593 
     | 
    
         
            -
                    expect { @instance.send(:activerecord_columns, ' 
     | 
| 
      
 593 
     | 
    
         
            +
                    expect { @instance.send(:activerecord_columns, 'externalId') }.to raise_error(Scimitar::FilterError)
         
     | 
| 
       594 
594 
     | 
    
         
             
                  end
         
     | 
| 
       595 
595 
     | 
    
         | 
| 
       596 
596 
     | 
    
         
             
                  it 'complains about malformed declarations' do
         
     |