Skip to content

Treat null as undefined in match method of SCIMMY.Types.Filter class #11

Treat null as undefined in match method of SCIMMY.Types.Filter class

Treat null as undefined in match method of SCIMMY.Types.Filter class #11

GitHub Actions / Unit Test Results succeeded Jul 24, 2024 in 0s

697 passed, 0 failed and 0 skipped

Tests passed successfully

✅ results-report.json

697 tests were completed in 234ms with 697 passed, 0 failed and 0 skipped.

Test suite Passed Failed Skipped Time
test/lib/config.js 37✅ 4ms
test/lib/messages.js 6✅ 0ms
test/lib/messages/bulkrequest.js 29✅ 13ms
test/lib/messages/bulkresponse.js 5✅ 1ms
test/lib/messages/error.js 6✅ 0ms
test/lib/messages/listresponse.js 23✅ 8ms
test/lib/messages/patchop.js 38✅ 32ms
test/lib/messages/searchrequest.js 22✅ 4ms
test/lib/resources.js 24✅ 2ms
test/lib/resources/group.js 60✅ 23ms
test/lib/resources/resourcetype.js 19✅ 3ms
test/lib/resources/schema.js 19✅ 1ms
test/lib/resources/spconfig.js 17✅ 2ms
test/lib/resources/user.js 60✅ 23ms
test/lib/schemas.js 18✅ 1ms
test/lib/schemas/enterpriseuser.js 12✅ 5ms
test/lib/schemas/group.js 12✅ 2ms
test/lib/schemas/resourcetype.js 12✅ 2ms
test/lib/schemas/spconfig.js 12✅ 4ms
test/lib/schemas/user.js 12✅ 3ms
test/lib/types.js 6✅ 0ms
test/lib/types/attribute.js 46✅ 11ms
test/lib/types/definition.js 57✅ 13ms
test/lib/types/error.js 7✅ 0ms
test/lib/types/filter.js 40✅ 16ms
test/lib/types/resource.js 79✅ 3ms
test/lib/types/schema.js 14✅ 3ms
test/scimmy.js 5✅ 0ms

✅ test/lib/config.js

SCIMMY.Config .get()
  ✅ should be implemented
  ✅ should return an immutable object
SCIMMY.Config .set()
  ✅ should accept boolean value 'false' for 'documentationUri' attribute
  ✅ should accept complex value 'supported' for 'bulk' attribute
  ✅ should accept complex value 'supported' for 'changePassword' attribute
  ✅ should accept complex value 'supported' for 'etag' attribute
  ✅ should accept complex value 'supported' for 'filter' attribute
  ✅ should accept complex value 'supported' for 'patch' attribute
  ✅ should accept complex value 'supported' for 'sort' attribute
  ✅ should accept shorthand boolean values 'true' and 'false' for 'bulk' attribute
  ✅ should accept shorthand boolean values 'true' and 'false' for 'changePassword' attribute
  ✅ should accept shorthand boolean values 'true' and 'false' for 'etag' attribute
  ✅ should accept shorthand boolean values 'true' and 'false' for 'filter' attribute
  ✅ should accept shorthand boolean values 'true' and 'false' for 'patch' attribute
  ✅ should accept shorthand boolean values 'true' and 'false' for 'sort' attribute
  ✅ should accept shorthand positive integer value for 'bulk' attribute
  ✅ should accept shorthand positive integer value for 'filter' attribute
  ✅ should accept string value 'https://example.com' for 'documentationUri' attribute
  ✅ should be implemented
  ✅ should do nothing without arguments
  ✅ should not accept boolean value 'true' for 'authenticationSchemes' attribute
  ✅ should not accept boolean value 'true' for 'documentationUri' attribute
  ✅ should not accept shorthand integer value for 'changePassword' attribute
  ✅ should not accept shorthand integer value for 'etag' attribute
  ✅ should not accept shorthand integer value for 'patch' attribute
  ✅ should not accept shorthand integer value for 'sort' attribute
  ✅ should not accept shorthand negative integer value for 'bulk' attribute
  ✅ should not accept shorthand negative integer value for 'filter' attribute
  ✅ should not accept shorthand string value for 'bulk' attribute
  ✅ should not accept shorthand string value for 'changePassword' attribute
  ✅ should not accept shorthand string value for 'etag' attribute
  ✅ should not accept shorthand string value for 'filter' attribute
  ✅ should not accept shorthand string value for 'patch' attribute
  ✅ should not accept shorthand string value for 'sort' attribute
  ✅ should not accept string value 'true' for 'documentationUri' attribute
  ✅ should not accept unknown attributes
  ✅ should return an immutable object

✅ test/lib/messages.js

SCIMMY.Messages
  ✅ should include static class 'BulkRequest'
  ✅ should include static class 'BulkResponse'
  ✅ should include static class 'Error'
  ✅ should include static class 'ListResponse'
  ✅ should include static class 'PatchOp'
  ✅ should include static class 'SearchRequest'

✅ test/lib/messages/bulkrequest.js

SCIMMY.Messages.BulkRequest @constructor
  ✅ should expect 'failOnErrors' attribute of 'request' argument to be a positive integer, if specified
  ✅ should expect 'maxOperations' argument to be a positive integer, if specified
  ✅ should expect 'Operations' attribute of 'request' argument to be an array
  ✅ should expect at least one bulk op in 'Operations' attribute of 'request' argument
  ✅ should expect number of operations to not exceed 'maxOperations' argument
  ✅ should not instantiate requests with invalid schemas
SCIMMY.Messages.BulkRequest #apply()
  ✅ should be implemented
  ✅ should call resource instance 'dispose' method when 'method' attribute value is DELETE
  ✅ should call resource instance 'patch' method when 'method' attribute value is PATCH
  ✅ should call resource instance 'write' method when 'method' attribute value is POST
  ✅ should call resource instance 'write' method when 'method' attribute value is PUT
  ✅ should dispose of newly created resources when circular bulkId operations fail
  ✅ should expect 'bulkId' attribute to be a string for each 'POST' operation
  ✅ should expect 'bulkId' attribute to have a value for each 'POST' operation
  ✅ should expect 'data' attribute to be a single complex value when 'method' is not DELETE
  ✅ should expect 'data' attribute to have a value when 'method' is not DELETE
  ✅ should expect 'method' attribute to be a string for each operation
  ✅ should expect 'method' attribute to be one of POST, PUT, PATCH, or DELETE for each operation
  ✅ should expect 'method' attribute to have a value for each operation
  ✅ should expect 'path' attribute not to specify a resource ID if 'method' is POST
  ✅ should expect 'path' attribute to be a string for each operation
  ✅ should expect 'path' attribute to have a value for each operation
  ✅ should expect 'path' attribute to refer to a valid resource type endpoint
  ✅ should expect 'path' attribute to specify a resource ID if 'method' is not POST
  ✅ should expect 'resourceTypes' argument to be an array of Resource type classes
  ✅ should handle precondition failures in dependent bulk operations
  ✅ should resolve bulkId references that are circular
  ✅ should resolve bulkId references that are out of order
  ✅ should stop processing operations when failOnErrors limit is reached

✅ test/lib/messages/bulkresponse.js

SCIMMY.Messages.BulkResponse @constructor
  ✅ should expect 'Operations' attribute of 'request' argument to be an array
  ✅ should not instantiate requests with invalid schemas
  ✅ should not require arguments
SCIMMY.Messages.BulkResponse #resolve()
  ✅ should be implemented
  ✅ should return an instance of native Map class

✅ test/lib/messages/error.js

SCIMMY.Messages.Error
  ✅ should extend native 'Error' class
SCIMMY.Messages.Error @constructor
  ✅ should not accept invalid HTTP status codes for 'status' parameter
  ✅ should not accept unknown values for 'scimType' parameter
  ✅ should not require arguments
  ✅ should rethrow inbound SCIM Error messages at instantiation
  ✅ should verify 'scimType' value is valid for a given 'status' code

✅ test/lib/messages/listresponse.js

SCIMMY.Messages.ListResponse @constructor
  ✅ should correctly sort resources if 'sortBy' parameter is supplied
  ✅ should expect 'itemsPerPage' parameter to be a positive integer
  ✅ should expect 'sortBy' parameter to be a string
  ✅ should expect 'sortOrder' parameter to be either 'ascending' or 'descending' if 'sortBy' parameter is defined
  ✅ should expect 'startIndex' parameter to be a positive integer
  ✅ should ignore 'sortOrder' parameter if 'sortBy' parameter is not defined
  ✅ should not accept requests with invalid schemas
  ✅ should not require arguments
  ✅ should only sort resources if 'sortBy' parameter is supplied
SCIMMY.Messages.ListResponse #itemsPerPage
  ✅ should be a positive integer
  ✅ should be defined
  ✅ should equal 'itemsPerPage' value included in inbound requests
SCIMMY.Messages.ListResponse #Resources
  ✅ should be an array
  ✅ should be defined
  ✅ should not include more resources than 'itemsPerPage' parameter
SCIMMY.Messages.ListResponse #startIndex
  ✅ should be a positive integer
  ✅ should be defined
SCIMMY.Messages.ListResponse #startIndex when parsing inbound messages
  ✅ should equal 'startIndex' value included in message
SCIMMY.Messages.ListResponse #startIndex when preparing outbound messages
  ✅ should be honoured if 'totalResults' is less than 'itemsPerPage'
  ✅ should be honoured if results are not already paginated
SCIMMY.Messages.ListResponse #totalResults
  ✅ should be a positive integer
  ✅ should be defined
  ✅ should equal 'totalResults' value included in inbound requests

✅ test/lib/messages/patchop.js

SCIMMY.Messages.PatchOp @constructor
  ✅ should expect 'Operations' attribute of 'request' parameter to be an array
  ✅ should expect all 'add' ops to have a 'value' value in 'Operations' attribute of 'request' parameter
  ✅ should expect all 'remove' ops to have a 'path' value in 'Operations' attribute of 'request' parameter
  ✅ should expect all patch op 'path' values to be strings in 'Operations' attribute of 'request' parameter
  ✅ should expect all patch ops to be 'complex' values in 'Operations' attribute of 'request' parameter
  ✅ should expect all patch ops to have an 'op' value in 'Operations' attribute of 'request' parameter
  ✅ should expect at least one patch op in 'Operations' attribute of 'request' parameter
  ✅ should ignore case of 'op' values in 'Operations' attribute of 'request' parameter
  ✅ should not accept unknown 'op' values in 'Operations' attribute of 'request' parameter
  ✅ should not instantiate requests with invalid schemas
SCIMMY.Messages.PatchOp #apply()
  ✅ should be implemented
  ✅ should expect 'resource' parameter to be an instance of SCIMMY.Types.Schema
  ✅ should expect 'resource' parameter to be defined
  ✅ should expect 'value' to be an object when 'path' is not specified in 'add' operations
  ✅ should expect 'value' to be an object when 'path' is not specified in 'replace' operations
  ✅ should expect all targeted attributes to exist in 'add' operations
  ✅ should expect all targeted attributes to exist in 'remove' operations
  ✅ should expect all targeted attributes to exist in 'replace' operations
  ✅ should expect message to be dispatched before 'apply' is called
  ✅ should not remove required attributes in 'add' operations
  ✅ should not remove required attributes in 'remove' operations
  ✅ should not remove required attributes in 'replace' operations
  ✅ should reject unknown 'op' values in operations
  ✅ should respect attribute mutability in 'add' operations
  ✅ should respect attribute mutability in 'remove' operations
  ✅ should respect attribute mutability in 'replace' operations
  ✅ should rethrow extensibility errors as SCIMErrors when 'path' points to nonexistent attribute in 'add' operations
  ✅ should rethrow extensibility errors as SCIMErrors when 'path' points to nonexistent attribute in 'replace' operations
  ✅ should rethrow other exceptions as SCIMErrors with location details in 'add' operations
  ✅ should rethrow other exceptions as SCIMErrors with location details in 'remove' operations
  ✅ should rethrow other exceptions as SCIMErrors with location details in 'replace' operations
  ✅ should rethrow SCIMErrors with added location details in 'add' operations
  ✅ should rethrow SCIMErrors with added location details in 'remove' operations
  ✅ should rethrow SCIMErrors with added location details in 'replace' operations
  ✅ should return nothing when applied PatchOp does not modify resource
  ✅ should support simple and complex 'add' operations
  ✅ should support simple and complex 'remove' operations
  ✅ should support simple and complex 'replace' operations

✅ test/lib/messages/searchrequest.js

SCIMMY.Messages.SearchRequest @constructor
  ✅ should expect 'attributes' property of 'request' argument to be an array of non-empty strings, if specified
  ✅ should expect 'count' property of 'request' argument to be a positive integer, if specified
  ✅ should expect 'excludedAttributes' property of 'request' argument to be an array of non-empty strings, if specified
  ✅ should expect 'filter' property of 'request' argument to be a non-empty string, if specified
  ✅ should expect 'sortBy' property of 'request' argument to be a non-empty string, if specified
  ✅ should expect 'sortOrder' property of 'request' argument to be either 'ascending' or 'descending', if specified
  ✅ should expect 'startIndex' property of 'request' argument to be a positive integer, if specified
  ✅ should not instantiate requests with invalid schemas
  ✅ should not require arguments
SCIMMY.Messages.SearchRequest #apply()
  ✅ should be implemented
  ✅ should call through to Resource type when only one given in 'resourceTypes' argument
  ✅ should expect 'resourceTypes' argument to be an array of Resource type classes
  ✅ should return a ListResponse message instance
SCIMMY.Messages.SearchRequest #prepare()
  ✅ should be implemented
  ✅ should expect 'attributes' property of 'request' params to be an array of non-empty strings, if specified
  ✅ should expect 'count' property of 'params' argument to be a positive integer, if specified
  ✅ should expect 'excludedAttributes' property of 'params' argument to be an array of non-empty strings, if specified
  ✅ should expect 'filter' property of 'params' argument to be a non-empty string, if specified
  ✅ should expect 'sortBy' property of 'params' argument to be a non-empty string, if specified
  ✅ should expect 'sortOrder' property of 'params' argument to be either 'ascending' or 'descending', if specified
  ✅ should expect 'startIndex' property of 'params' argument to be a positive integer, if specified
  ✅ should return the same instance it was called from

✅ test/lib/resources.js

SCIMMY.Resources
  ✅ should include static class 'Group'
  ✅ should include static class 'ResourceType'
  ✅ should include static class 'Schema'
  ✅ should include static class 'ServiceProviderConfig'
  ✅ should include static class 'User'
SCIMMY.Resources .declare()
  ✅ should be implemented
  ✅ should call resource's 'basepath' static method if 'basepath' property of 'config' argument is a string
  ✅ should call resource's 'degress' static method if 'degress' property of 'config' argument is a function
  ✅ should call resource's 'egress' static method if 'egress' property of 'config' argument is a function
  ✅ should call resource's 'extend' static method if 'extensions' property of 'config' argument is an array
  ✅ should call resource's 'ingress' static method if 'ingress' property of 'config' argument is a function
  ✅ should declare resource type implementation's schema definition to Schemas
  ✅ should expect 'config' argument to be either a string or an object
  ✅ should expect 'resource' argument to be an instance of Resource
  ✅ should expect all resources to have unique names
  ✅ should not declare an existing resource under a new name
  ✅ should refuse to declare internal resource implementations 'Schema', 'ResourceType', and 'ServiceProviderConfig'
  ✅ should return resource after declaration if 'config' argument was not an object
  ✅ should return self after declaration if 'config' argument was an object
SCIMMY.Resources .declared()
  ✅ should be implemented
  ✅ should find declaration status of resource when 'resource' argument is a resource instance
  ✅ should find declared resource by name when 'resource' argument is a string
  ✅ should return all declared resources when called without arguments
  ✅ should return boolean 'false' when called with unexpected arguments

✅ test/lib/resources/group.js

SCIMMY.Resources.Group .basepath()
  ✅ should be implemented
  ✅ should be mutable
SCIMMY.Resources.Group .degress()
  ✅ should be implemented
  ✅ should set private degress handler
SCIMMY.Resources.Group .egress()
  ✅ should be implemented
  ✅ should set private egress handler
SCIMMY.Resources.Group .endpoint
  ✅ should be a string
  ✅ should be implemented
SCIMMY.Resources.Group .extend()
  ✅ should not be overridden
SCIMMY.Resources.Group .ingress()
  ✅ should be implemented
  ✅ should set private ingress handler
SCIMMY.Resources.Group .schema
  ✅ should be an instance of Schema
  ✅ should be implemented
SCIMMY.Resources.Group @constructor
  ✅ should expect 'attributes' property of query parameters to be a comma-separated list string
  ✅ should expect 'excludedAttributes' property of query parameters to be a comma-separated list string
  ✅ should expect 'filter' property of query parameters to be a non-empty string
  ✅ should expect 'id' argument to be a non-empty string, if supplied
  ✅ should expect query parameters to be an object
  ✅ should not require arguments
SCIMMY.Resources.Group #dispose()
  ✅ should be implemented
  ✅ should call degress handler method with originating resource instance as an argument
  ✅ should call degress method with supplied context as an argument
  ✅ should call degress to delete a resource instance
  ✅ should expect a resource with supplied ID to exist
  ✅ should expect resource instances to have 'id' property
  ✅ should rethrow SCIMErrors thrown by handler
  ✅ should rethrow TypeErrors thrown by handler as SCIMErrors
SCIMMY.Resources.Group #patch()
  ✅ should be implemented
  ✅ should call egress handler before ingress handler
  ✅ should call egress handler method exactly once
  ✅ should call egress handler method with originating resource instance as an argument
  ✅ should call egress handler method with supplied context as an argument
  ✅ should call ingress handler method exactly once
  ✅ should call ingress handler method with originating resource instance as an argument
  ✅ should call ingress handler method with supplied context as an argument
  ✅ should expect 'message' argument to be an object
  ✅ should expect a resource with supplied ID to exist
  ✅ should rethrow SCIMErrors thrown by handlers
  ✅ should rethrow TypeErrors thrown by handlers as SCIMErrors
  ✅ should return nothing when applied PatchOp does not modify resource
  ✅ should return the full resource when applied PatchOp modifies resource
SCIMMY.Resources.Group #read()
  ✅ should be implemented
  ✅ should call egress handler method with originating resource instance as an argument
  ✅ should call egress method with supplied context as an argument
  ✅ should call egress to return a ListResponse if resource was instantiated without an ID
  ✅ should call egress to return the requested resource instance if resource was instantiated with an ID
  ✅ should expect a resource with supplied ID to exist
  ✅ should honour 'startIndex' constraint in ListResponse if resource was instantiated without an ID
  ✅ should rethrow SCIMErrors thrown by handler
  ✅ should rethrow TypeErrors thrown by handler as SCIMErrors
  ✅ should treat length of array returned by egress method as 'totalResults' value in ListResponse if resource was instantiated without an ID
SCIMMY.Resources.Group #write()
  ✅ should be implemented
  ✅ should call ingress handler method with originating resource instance as an argument
  ✅ should call ingress method with supplied context as an argument
  ✅ should call ingress to create new resources when resource instantiated without ID
  ✅ should call ingress to update existing resources when resource instantiated with ID
  ✅ should expect 'instance' argument to be an object
  ✅ should expect a resource with supplied ID to exist
  ✅ should rethrow SCIMErrors thrown by handler
  ✅ should rethrow TypeErrors thrown by handler as SCIMErrors

✅ test/lib/resources/resourcetype.js

SCIMMY.Resources.ResourceType .basepath()
  ✅ should be implemented
  ✅ should be mutable
SCIMMY.Resources.ResourceType .degress()
  ✅ should not be implemented
SCIMMY.Resources.ResourceType .egress()
  ✅ should not be implemented
SCIMMY.Resources.ResourceType .endpoint
  ✅ should be a string
  ✅ should be implemented
SCIMMY.Resources.ResourceType .extend()
  ✅ should be overridden
  ✅ should throw an 'unsupported' error
SCIMMY.Resources.ResourceType .ingress()
  ✅ should not be implemented
SCIMMY.Resources.ResourceType .schema
  ✅ should not be implemented
SCIMMY.Resources.ResourceType @constructor
  ✅ should not instantiate when a filter has been specified
  ✅ should not require arguments
SCIMMY.Resources.ResourceType #dispose()
  ✅ should not be implemented
SCIMMY.Resources.ResourceType #patch()
  ✅ should not be implemented
SCIMMY.Resources.ResourceType #read()
  ✅ should be implemented
  ✅ should expect a resource with supplied ID to exist
  ✅ should return a ListResponse if resource was instantiated without an ID
  ✅ should return the requested resource instance if resource was instantiated with an ID
SCIMMY.Resources.ResourceType #write()
  ✅ should not be implemented

✅ test/lib/resources/schema.js

SCIMMY.Resources.Schema .basepath()
  ✅ should be implemented
  ✅ should be mutable
SCIMMY.Resources.Schema .degress()
  ✅ should not be implemented
SCIMMY.Resources.Schema .egress()
  ✅ should not be implemented
SCIMMY.Resources.Schema .endpoint
  ✅ should be a string
  ✅ should be implemented
SCIMMY.Resources.Schema .extend()
  ✅ should be overridden
  ✅ should throw an 'unsupported' error
SCIMMY.Resources.Schema .ingress()
  ✅ should not be implemented
SCIMMY.Resources.Schema .schema
  ✅ should not be implemented
SCIMMY.Resources.Schema @constructor
  ✅ should not instantiate when a filter has been specified
  ✅ should not require arguments
SCIMMY.Resources.Schema #dispose()
  ✅ should not be implemented
SCIMMY.Resources.Schema #patch()
  ✅ should not be implemented
SCIMMY.Resources.Schema #read()
  ✅ should be implemented
  ✅ should expect a resource with supplied ID to exist
  ✅ should return a ListResponse if resource was instantiated without an ID
  ✅ should return the requested resource instance if resource was instantiated with an ID
SCIMMY.Resources.Schema #write()
  ✅ should not be implemented

✅ test/lib/resources/spconfig.js

SCIMMY.Resources.ServiceProviderConfig .basepath()
  ✅ should be implemented
  ✅ should be mutable
SCIMMY.Resources.ServiceProviderConfig .degress()
  ✅ should not be implemented
SCIMMY.Resources.ServiceProviderConfig .egress()
  ✅ should not be implemented
SCIMMY.Resources.ServiceProviderConfig .endpoint
  ✅ should be a string
  ✅ should be implemented
SCIMMY.Resources.ServiceProviderConfig .extend()
  ✅ should be overridden
  ✅ should throw an 'unsupported' error
SCIMMY.Resources.ServiceProviderConfig .ingress()
  ✅ should not be implemented
SCIMMY.Resources.ServiceProviderConfig .schema
  ✅ should not be implemented
SCIMMY.Resources.ServiceProviderConfig @constructor
  ✅ should not instantiate when a filter has been specified
  ✅ should not require arguments
SCIMMY.Resources.ServiceProviderConfig #dispose()
  ✅ should not be implemented
SCIMMY.Resources.ServiceProviderConfig #patch()
  ✅ should not be implemented
SCIMMY.Resources.ServiceProviderConfig #read()
  ✅ should be implemented
  ✅ should return the requested resource without sugar-coating
SCIMMY.Resources.ServiceProviderConfig #write()
  ✅ should not be implemented

✅ test/lib/resources/user.js

SCIMMY.Resources.User .basepath()
  ✅ should be implemented
  ✅ should be mutable
SCIMMY.Resources.User .degress()
  ✅ should be implemented
  ✅ should set private degress handler
SCIMMY.Resources.User .egress()
  ✅ should be implemented
  ✅ should set private egress handler
SCIMMY.Resources.User .endpoint
  ✅ should be a string
  ✅ should be implemented
SCIMMY.Resources.User .extend()
  ✅ should not be overridden
SCIMMY.Resources.User .ingress()
  ✅ should be implemented
  ✅ should set private ingress handler
SCIMMY.Resources.User .schema
  ✅ should be an instance of Schema
  ✅ should be implemented
SCIMMY.Resources.User @constructor
  ✅ should expect 'attributes' property of query parameters to be a comma-separated list string
  ✅ should expect 'excludedAttributes' property of query parameters to be a comma-separated list string
  ✅ should expect 'filter' property of query parameters to be a non-empty string
  ✅ should expect 'id' argument to be a non-empty string, if supplied
  ✅ should expect query parameters to be an object
  ✅ should not require arguments
SCIMMY.Resources.User #dispose()
  ✅ should be implemented
  ✅ should call degress handler method with originating resource instance as an argument
  ✅ should call degress method with supplied context as an argument
  ✅ should call degress to delete a resource instance
  ✅ should expect a resource with supplied ID to exist
  ✅ should expect resource instances to have 'id' property
  ✅ should rethrow SCIMErrors thrown by handler
  ✅ should rethrow TypeErrors thrown by handler as SCIMErrors
SCIMMY.Resources.User #patch()
  ✅ should be implemented
  ✅ should call egress handler before ingress handler
  ✅ should call egress handler method exactly once
  ✅ should call egress handler method with originating resource instance as an argument
  ✅ should call egress handler method with supplied context as an argument
  ✅ should call ingress handler method exactly once
  ✅ should call ingress handler method with originating resource instance as an argument
  ✅ should call ingress handler method with supplied context as an argument
  ✅ should expect 'message' argument to be an object
  ✅ should expect a resource with supplied ID to exist
  ✅ should rethrow SCIMErrors thrown by handlers
  ✅ should rethrow TypeErrors thrown by handlers as SCIMErrors
  ✅ should return nothing when applied PatchOp does not modify resource
  ✅ should return the full resource when applied PatchOp modifies resource
SCIMMY.Resources.User #read()
  ✅ should be implemented
  ✅ should call egress handler method with originating resource instance as an argument
  ✅ should call egress method with supplied context as an argument
  ✅ should call egress to return a ListResponse if resource was instantiated without an ID
  ✅ should call egress to return the requested resource instance if resource was instantiated with an ID
  ✅ should expect a resource with supplied ID to exist
  ✅ should honour 'startIndex' constraint in ListResponse if resource was instantiated without an ID
  ✅ should rethrow SCIMErrors thrown by handler
  ✅ should rethrow TypeErrors thrown by handler as SCIMErrors
  ✅ should treat length of array returned by egress method as 'totalResults' value in ListResponse if resource was instantiated without an ID
SCIMMY.Resources.User #write()
  ✅ should be implemented
  ✅ should call ingress handler method with originating resource instance as an argument
  ✅ should call ingress method with supplied context as an argument
  ✅ should call ingress to create new resources when resource instantiated without ID
  ✅ should call ingress to update existing resources when resource instantiated with ID
  ✅ should expect 'instance' argument to be an object
  ✅ should expect a resource with supplied ID to exist
  ✅ should rethrow SCIMErrors thrown by handler
  ✅ should rethrow TypeErrors thrown by handler as SCIMErrors

✅ test/lib/schemas.js

SCIMMY.Schemas
  ✅ should include static class 'EnterpriseUser'
  ✅ should include static class 'Group'
  ✅ should include static class 'ResourceType'
  ✅ should include static class 'ServiceProviderConfig'
  ✅ should include static class 'User'
SCIMMY.Schemas .declare()
  ✅ should always return self after declaration
  ✅ should be implemented
  ✅ should expect 'definition' argument to be an instance of SchemaDefinition
  ✅ should expect all schema definitions to have unique names
  ✅ should ignore definition instances that are already declared with the same name
  ✅ should not declare an existing schema definition under a new name
SCIMMY.Schemas .declared()
  ✅ should be implemented
  ✅ should find declaration status of definitions by ID
  ✅ should find declaration status of definitions by instance
  ✅ should find declaration status of definitions by name
  ✅ should find nested schema extension definition instances
  ✅ should return all declared definitions when called without arguments
  ✅ should return boolean 'false' when called with unexpected arguments

✅ test/lib/schemas/enterpriseuser.js

SCIMMY.Schemas.EnterpriseUser .definition
  ✅ should be an instance of SchemaDefinition
  ✅ should be defined
  ✅ should produce definition object that matches sample schemas defined in RFC7643
SCIMMY.Schemas.EnterpriseUser @constructor
  ✅ should be frozen after instantiation
  ✅ should clean up empty extension schema properties
  ✅ should coerce complex multi-value attributes in schema extensions
  ✅ should define getters and setters for all attributes in the schema definition
  ✅ should expect errors in extension schema coercion to be rethrown as SCIMErrors
  ✅ should include extension schema attribute property accessor aliases
  ✅ should include lower-case attribute name property accessor aliases
  ✅ should require 'resource' parameter to be an object at instantiation
  ✅ should validate 'schemas' property of 'resource' parameter if it is defined

✅ test/lib/schemas/group.js

SCIMMY.Schemas.Group .definition
  ✅ should be an instance of SchemaDefinition
  ✅ should be defined
  ✅ should produce definition object that matches sample schemas defined in RFC7643
SCIMMY.Schemas.Group @constructor
  ✅ should be frozen after instantiation
  ✅ should clean up empty extension schema properties
  ✅ should coerce complex multi-value attributes in schema extensions
  ✅ should define getters and setters for all attributes in the schema definition
  ✅ should expect errors in extension schema coercion to be rethrown as SCIMErrors
  ✅ should include extension schema attribute property accessor aliases
  ✅ should include lower-case attribute name property accessor aliases
  ✅ should require 'resource' parameter to be an object at instantiation
  ✅ should validate 'schemas' property of 'resource' parameter if it is defined

✅ test/lib/schemas/resourcetype.js

SCIMMY.Schemas.ResourceType .definition
  ✅ should be an instance of SchemaDefinition
  ✅ should be defined
  ✅ should produce definition object that matches sample schemas defined in RFC7643
SCIMMY.Schemas.ResourceType @constructor
  ✅ should be frozen after instantiation
  ✅ should clean up empty extension schema properties
  ✅ should coerce complex multi-value attributes in schema extensions
  ✅ should define getters and setters for all attributes in the schema definition
  ✅ should expect errors in extension schema coercion to be rethrown as SCIMErrors
  ✅ should include extension schema attribute property accessor aliases
  ✅ should include lower-case attribute name property accessor aliases
  ✅ should require 'resource' parameter to be an object at instantiation
  ✅ should validate 'schemas' property of 'resource' parameter if it is defined

✅ test/lib/schemas/spconfig.js

SCIMMY.Schemas.ServiceProviderConfig .definition
  ✅ should be an instance of SchemaDefinition
  ✅ should be defined
  ✅ should produce definition object that matches sample schemas defined in RFC7643
SCIMMY.Schemas.ServiceProviderConfig @constructor
  ✅ should be frozen after instantiation
  ✅ should clean up empty extension schema properties
  ✅ should coerce complex multi-value attributes in schema extensions
  ✅ should define getters and setters for all attributes in the schema definition
  ✅ should expect errors in extension schema coercion to be rethrown as SCIMErrors
  ✅ should include extension schema attribute property accessor aliases
  ✅ should include lower-case attribute name property accessor aliases
  ✅ should require 'resource' parameter to be an object at instantiation
  ✅ should validate 'schemas' property of 'resource' parameter if it is defined

✅ test/lib/schemas/user.js

SCIMMY.Schemas.User .definition
  ✅ should be an instance of SchemaDefinition
  ✅ should be defined
  ✅ should produce definition object that matches sample schemas defined in RFC7643
SCIMMY.Schemas.User @constructor
  ✅ should be frozen after instantiation
  ✅ should clean up empty extension schema properties
  ✅ should coerce complex multi-value attributes in schema extensions
  ✅ should define getters and setters for all attributes in the schema definition
  ✅ should expect errors in extension schema coercion to be rethrown as SCIMErrors
  ✅ should include extension schema attribute property accessor aliases
  ✅ should include lower-case attribute name property accessor aliases
  ✅ should require 'resource' parameter to be an object at instantiation
  ✅ should validate 'schemas' property of 'resource' parameter if it is defined

✅ test/lib/types.js

SCIMMY.Types
  ✅ should include static class 'Attribute'
  ✅ should include static class 'Error'
  ✅ should include static class 'Filter'
  ✅ should include static class 'Resource'
  ✅ should include static class 'Schema'
  ✅ should include static class 'SchemaDefinition'

✅ test/lib/types/attribute.js

SCIMMY.Types.Attribute @constructor
  ✅ should be frozen after instantiation
  ✅ should not accept 'subAttributes' argument if type is not 'complex'
  ✅ should not accept invalid 'canonicalValues' configuration values
  ✅ should not accept invalid 'mutable' configuration values
  ✅ should not accept invalid 'referenceTypes' configuration values
  ✅ should not accept invalid 'returned' configuration values
  ✅ should not accept invalid 'uniqueness' configuration values
  ✅ should require valid 'name' argument
  ✅ should require valid 'type' argument
SCIMMY.Types.Attribute #coerce()
  ✅ should be implemented
  ✅ should do nothing when 'type' is unrecognised
  ✅ should expect all subAttribute values to be wrapped when attribute is multi-valued and type is 'complex'
  ✅ should expect all values to be base64 encoded strings when attribute is multi-valued and type is 'binary'
  ✅ should expect all values to be canonical when attribute is multi-valued and specifies canonicalValues characteristic
  ✅ should expect all values to be decimal numbers when attribute is multi-valued and type is 'decimal'
  ✅ should expect all values to be either true or false when attribute is multi-valued and type is 'boolean'
  ✅ should expect all values to be integer numbers when attribute is multi-valued and type is 'integer'
  ✅ should expect all values to be objects when attribute is multi-valued and type is 'complex'
  ✅ should expect all values to be strings when attribute is multi-valued and type is 'string'
  ✅ should expect all values to be valid date instances or date strings when attribute is multi-valued and type is 'dateTime'
  ✅ should expect all values to be valid references when attribute is multi-valued and type is 'reference'
  ✅ should expect required attributes to have a value
  ✅ should expect subAttribute values to be wrapped when attribute type is 'complex'
  ✅ should expect value to be a base64 encoded string when attribute type is 'binary'
  ✅ should expect value to be a decimal number when attribute type is 'decimal'
  ✅ should expect value to be a string when attribute type is 'string'
  ✅ should expect value to be a valid date instance or date string when attribute type is 'dateTime'
  ✅ should expect value to be a valid reference when attribute type is 'reference'
  ✅ should expect value to be an array when attribute is multi-valued
  ✅ should expect value to be an integer number when attribute type is 'integer'
  ✅ should expect value to be an object when attribute type is 'complex'
  ✅ should expect value to be canonical when attribute specifies canonicalValues characteristic
  ✅ should expect value to be either true or false when attribute type is 'boolean'
  ✅ should expect value to be singular when attribute is not multi-valued
SCIMMY.Types.Attribute #subAttributes
  ✅ should be an array when type is 'complex'
  ✅ should expect new values to be Attribute instances
  ✅ should not be defined when type is not 'complex'
SCIMMY.Types.Attribute #toJSON()
  ✅ should be implemented
  ✅ should not include shadow sub-attributes
  ✅ should produce valid SCIM attribute definition objects
SCIMMY.Types.Attribute #truncate()
  ✅ should be implemented
  ✅ should do nothing when specified sub-attribute instance does not exist
  ✅ should do nothing when type is not 'complex'
  ✅ should do nothing without arguments
  ✅ should find sub-attribute instance by name and remove from 'subAttributes' collection
  ✅ should remove specified sub-attribute instance from 'subAttributes' collection

✅ test/lib/types/definition.js

SCIMMY.Types.SchemaDefinition @constructor
  ✅ should expect 'name' argument to be defined
  ✅ should require 'id' to start with 'urn:ietf:params:scim:schemas:'
  ✅ should require valid 'description' argument
  ✅ should require valid 'id' argument
SCIMMY.Types.SchemaDefinition #attribute()
  ✅ should be implemented
  ✅ should expect attributes to exist
  ✅ should expect namespaced attributes to exist
  ✅ should expect sub-attributes to exist
  ✅ should find attributes by name
  ✅ should find namespaced attributes
  ✅ should find sub-attributes by name
  ✅ should ignore case of 'name' argument when finding attributes
  ✅ should ignore case of 'name' argument when finding namespaced attributes
  ✅ should ignore case of 'name' argument when finding sub-attributes
SCIMMY.Types.SchemaDefinition #attributes
  ✅ should be an array
  ✅ should be defined
SCIMMY.Types.SchemaDefinition #coerce()
  ✅ should be implemented
  ✅ should expect 'data' argument to be an object
  ✅ should expect coerce to be called on directly included attributes
  ✅ should expect coerce to be called on included schema extensions
  ✅ should expect common attributes to be defined on coerced result
  ✅ should expect complex multi-valued attributes to be filtered negatively
  ✅ should expect complex multi-valued attributes to be filtered positively
  ✅ should expect deeply nested namespaced and extension attributes to be merged and coerced
  ✅ should expect namespaced attributes in the supplied filter to be applied to coerced result
  ✅ should expect namespaced attributes or extensions to be coerced
  ✅ should expect negative filters to be applied to coerced results
  ✅ should expect required schema extensions to be defined
  ✅ should expect the supplied filter to be applied to coerced result
SCIMMY.Types.SchemaDefinition #describe()
  ✅ should be implemented
  ✅ should produce valid SCIM schema definition objects
SCIMMY.Types.SchemaDefinition #description
  ✅ should be a string
  ✅ should be defined
  ✅ should equal 'description' argument supplied at instantiation
SCIMMY.Types.SchemaDefinition #extend()
  ✅ should be implemented
  ✅ should do nothing when Attribute instance extensions are already included in the schema definition
  ✅ should do nothing when SchemaDefinition instances are already declared as extensions to the schema definition
  ✅ should expect 'extension' argument to be an instance of SchemaDefinition or collection of Attribute instances
  ✅ should expect all attribute extensions to have unique names
  ✅ should expect all schema definition extensions to have unique IDs
SCIMMY.Types.SchemaDefinition #id
  ✅ should be a string
  ✅ should be defined
  ✅ should equal 'id' argument supplied at instantiation
SCIMMY.Types.SchemaDefinition #name
  ✅ should be a string
  ✅ should be defined
  ✅ should equal 'name' argument supplied at instantiation
SCIMMY.Types.SchemaDefinition #truncate()
  ✅ should be implemented
  ✅ should do nothing without arguments
SCIMMY.Types.SchemaDefinition #truncate() when 'targets' argument contains a SchemaDefinition instance
  ✅ should expect definition to directly include the instance
  ✅ should remove instances directly included in the definition
SCIMMY.Types.SchemaDefinition #truncate() when 'targets' argument contains a string
  ✅ should expect named attributes and sub-attributes to exist
  ✅ should remove named attributes directly included in the definition
  ✅ should remove named sub-attributes included in the definition
SCIMMY.Types.SchemaDefinition #truncate() when 'targets' argument contains an array of Attribute instances
  ✅ should do nothing when definition does not directly include the instances
  ✅ should remove instances directly included in the definition
SCIMMY.Types.SchemaDefinition #truncate() when 'targets' argument contains an Attribute instance
  ✅ should do nothing when definition does not directly include the instances
  ✅ should remove instances directly included in the definition

✅ test/lib/types/error.js

SCIMMY.Types.Error
  ✅ should extend native 'Error' class
SCIMMY.Types.Error @constructor
  ✅ should not require arguments
SCIMMY.Types.Error #message
  ✅ should be defined
SCIMMY.Types.Error #name
  ✅ should be defined
  ✅ should have value 'SCIMError'
SCIMMY.Types.Error #scimType
  ✅ should be defined
SCIMMY.Types.Error #status
  ✅ should be defined

✅ test/lib/types/filter.js

SCIMMY.Types.Filter
  ✅ should extend native 'Array' class
SCIMMY.Types.Filter @constructor
  ✅ should not require arguments
SCIMMY.Types.Filter @constructor when 'expression' argument is a string
  ✅ should be a well formed SCIM filter string expression
  ✅ should expect all grouping operators to be opened and closed
  ✅ should not be empty
  ✅ should parse complex expressions with a mix of logical and grouping operators
  ✅ should parse expressions with grouping operators
  ✅ should parse expressions with logical operators
  ✅ should parse simple expressions without logical or grouping operators
SCIMMY.Types.Filter @constructor when 'expression' argument is an array of objects
  ✅ should expect all object properties to not be empty objects
  ✅ should expect all properties to be arrays or plain objects
  ✅ should expect expression comparators to be defined
  ✅ should not contain any empty objects
  ✅ should throw when nested arrays are mixed with singular expressions
SCIMMY.Types.Filter @constructor when 'expression' argument is an object
  ✅ should expect all object properties to not be empty objects
  ✅ should expect all properties to be arrays or plain objects
  ✅ should expect expression comparators to be defined
  ✅ should not be an empty object
  ✅ should throw when nested arrays are mixed with singular expressions
SCIMMY.Types.Filter @constructor when 'expression' argument is defined
  ✅ should not be a primitive boolean
  ✅ should not be a primitive number
  ✅ should not be an instance of Date
SCIMMY.Types.Filter #expression when 'expression' argument was a string at instantiation
  ✅ should always equal supplied 'expression' string argument
  ✅ should be a string
  ✅ should be defined
SCIMMY.Types.Filter #expression when 'expression' argument was an object, or array of objects at instantiation
  ✅ should be a string
  ✅ should be defined
  ✅ should stringify complex expression objects with multiple branches and joins
  ✅ should stringify expression objects with logical operators
  ✅ should stringify simple expression objects without logical or grouping operators
SCIMMY.Types.Filter #match()
  ✅ should be implemented
  ✅ should correctly compare ISO 8601 datetime string attribute values
  ✅ should correctly compare numeric attribute values
  ✅ should handle matches for known comparison expressions
  ✅ should handle matches with negation expressions
  ✅ should handle matching of nested attributes
  ✅ should match attribute names in a case-insensitive manner
  ✅ should match values against all expressions in a group of logical 'and' expressions for a single attribute
  ✅ should match values against any one expression in a group of logical 'or' expressions
  ✅ should not match unknown comparators

✅ test/lib/types/resource.js

SCIMMY.Types.Resource .basepath()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource .degress()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource .describe()
  ✅ should be implemented
  ✅ should expect 'description' property of description to equal 'description' property of resource's schema definition
  ✅ should expect 'endpoint' property of description to equal 'name' property of resource's schema definition, with leading forward-slash
  ✅ should expect 'id' property of description to equal 'name' property of resource's schema definition
  ✅ should expect 'name' property of description to equal 'name' property of resource's schema definition
  ✅ should expect 'schema' property of description to equal 'id' property of resource's schema definition
  ✅ should expect 'schemaExtensions' property to be excluded in description when resource is not extended
  ✅ should expect 'schemaExtensions' property to be included in description when resource is extended
SCIMMY.Types.Resource .egress()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource .endpoint
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource .extend()
  ✅ should be implemented
SCIMMY.Types.Resource .ingress()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource .schema
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource #attributes when 'attributes' query parameter was defined
  ✅ should be an instance of Filter
  ✅ should expect filter expression to be 'present'
  ✅ should expect filter expression to be 'present' for all specified attributes
  ✅ should take precedence over 'excludedAttributes' when both defined
SCIMMY.Types.Resource #attributes when 'excludedAttributes' query parameter was defined
  ✅ should be an instance of Filter
  ✅ should expect filter expression to be 'not present'
  ✅ should expect filter expression to be 'not present' for all specified attributes
SCIMMY.Types.Resource #constraints when 'count' query parameter was defined
  ✅ should be an object
  ✅ should include 'count' property equal to 'count' query parameter value when it was valid
  ✅ should include other valid properties when 'count' query parameter had invalid array value
  ✅ should include other valid properties when 'count' query parameter had invalid boolean value 'false'
  ✅ should include other valid properties when 'count' query parameter had invalid object value
  ✅ should include other valid properties when 'count' query parameter had invalid string value 'a string'
  ✅ should not include 'count' property when 'count' query parameter had invalid array value
  ✅ should not include 'count' property when 'count' query parameter had invalid boolean value 'false'
  ✅ should not include 'count' property when 'count' query parameter had invalid object value
  ✅ should not include 'count' property when 'count' query parameter had invalid string value 'a string'
SCIMMY.Types.Resource #constraints when 'sortBy' query parameter was defined
  ✅ should be an object
  ✅ should include 'sortBy' property equal to 'sortBy' query parameter value when it was valid
  ✅ should include other valid properties when 'sortBy' query parameter had invalid array value
  ✅ should include other valid properties when 'sortBy' query parameter had invalid boolean value 'false'
  ✅ should include other valid properties when 'sortBy' query parameter had invalid number value '1'
  ✅ should include other valid properties when 'sortBy' query parameter had invalid object value
  ✅ should not include 'sortBy' property when 'sortBy' query parameter had invalid array value
  ✅ should not include 'sortBy' property when 'sortBy' query parameter had invalid boolean value 'false'
  ✅ should not include 'sortBy' property when 'sortBy' query parameter had invalid number value '1'
  ✅ should not include 'sortBy' property when 'sortBy' query parameter had invalid object value
SCIMMY.Types.Resource #constraints when 'sortOrder' query parameter was defined
  ✅ should be an object
  ✅ should include 'sortOrder' property equal to 'sortOrder' query parameter value when it was valid
  ✅ should include other valid properties when 'sortOrder' query parameter had invalid array value
  ✅ should include other valid properties when 'sortOrder' query parameter had invalid boolean value 'false'
  ✅ should include other valid properties when 'sortOrder' query parameter had invalid number value '1'
  ✅ should include other valid properties when 'sortOrder' query parameter had invalid object value
  ✅ should include other valid properties when 'sortOrder' query parameter had invalid string value 'a string'
  ✅ should not include 'sortOrder' property when 'sortOrder' query parameter had invalid array value
  ✅ should not include 'sortOrder' property when 'sortOrder' query parameter had invalid boolean value 'false'
  ✅ should not include 'sortOrder' property when 'sortOrder' query parameter had invalid number value '1'
  ✅ should not include 'sortOrder' property when 'sortOrder' query parameter had invalid object value
  ✅ should not include 'sortOrder' property when 'sortOrder' query parameter had invalid string value 'a string'
SCIMMY.Types.Resource #constraints when 'startIndex' query parameter was defined
  ✅ should be an object
  ✅ should include 'startIndex' property equal to 'startIndex' query parameter value when it was valid
  ✅ should include other valid properties when 'startIndex' query parameter had invalid array value
  ✅ should include other valid properties when 'startIndex' query parameter had invalid boolean value 'false'
  ✅ should include other valid properties when 'startIndex' query parameter had invalid object value
  ✅ should include other valid properties when 'startIndex' query parameter had invalid string value 'a string'
  ✅ should not include 'startIndex' property when 'startIndex' query parameter had invalid array value
  ✅ should not include 'startIndex' property when 'startIndex' query parameter had invalid boolean value 'false'
  ✅ should not include 'startIndex' property when 'startIndex' query parameter had invalid object value
  ✅ should not include 'startIndex' property when 'startIndex' query parameter had invalid string value 'a string'
SCIMMY.Types.Resource #dispose()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource #filter
  ✅ should be an instance of Filter
SCIMMY.Types.Resource #patch()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource #read()
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Resource #write()
  ✅ should be abstract
  ✅ should be defined

✅ test/lib/types/schema.js

SCIMMY.Types.Schema .definition
  ✅ should be abstract
  ✅ should be defined
SCIMMY.Types.Schema .extend()
  ✅ should be implemented
SCIMMY.Types.Schema .truncate()
  ✅ should be implemented
SCIMMY.Types.Schema @constructor
  ✅ should be frozen after instantiation
  ✅ should clean up empty extension schema properties
  ✅ should coerce complex multi-value attributes in schema extensions
  ✅ should define getters and setters for all attributes in the schema definition
  ✅ should expect errors in extension schema coercion to be rethrown as SCIMErrors
  ✅ should include 'toJSON' method that strips attributes where returned is marked as 'never'
  ✅ should include extension schema attribute property accessor aliases
  ✅ should include lower-case attribute name property accessor aliases
  ✅ should require 'resource' parameter to be an object at instantiation
  ✅ should validate 'schemas' property of 'resource' parameter if it is defined

✅ test/scimmy.js

SCIMMY
  ✅ should include static class 'Config'
  ✅ should include static class 'Messages'
  ✅ should include static class 'Resources'
  ✅ should include static class 'Schemas'
  ✅ should include static class 'Types'