cli
1# frozen_string_literal: true
2
3RSpec.describe Scim::Kit::Cli::Validator do
4 describe '.errors_for' do
5 let(:schema) do
6 {
7 'type' => 'object',
8 'properties' => { 'userName' => { 'type' => 'string' } },
9 'required' => ['userName'],
10 'additionalProperties' => false
11 }
12 end
13
14 it 'returns an empty array for a valid document' do
15 errors = described_class.errors_for(schema, { userName: 'bjensen' })
16
17 expect(errors).to eql([])
18 end
19
20 it 'returns a readable error for a missing required property' do
21 errors = described_class.errors_for(schema, {})
22
23 expect(errors).to eql(['root is missing required keys: userName'])
24 end
25
26 it 'returns a readable error for a wrong type' do
27 errors = described_class.errors_for(schema, { userName: 1 })
28
29 expect(errors).to eql(["property '/userName' is not of type: string"])
30 end
31
32 context 'with an optional attribute' do
33 let(:schema) do
34 {
35 'type' => 'object',
36 'properties' => {
37 'userName' => { 'type' => 'string' },
38 'externalId' => { 'type' => 'string' }
39 },
40 'required' => ['userName']
41 }
42 end
43
44 it 'accepts null, which RFC 7643 2.5 makes equivalent to unassigned' do
45 errors = described_class.errors_for(
46 schema, { userName: 'bjensen', externalId: nil }
47 )
48
49 expect(errors).to eql([])
50 end
51
52 it 'still reports a wrong type' do
53 errors = described_class.errors_for(
54 schema, { userName: 'bjensen', externalId: 1 }
55 )
56
57 expect(errors).to eql(["property '/externalId' is not of type: string"])
58 end
59 end
60
61 it 'reports null for a required attribute as unassigned' do
62 errors = described_class.errors_for(schema, { userName: nil })
63
64 expect(errors).to eql(['root is missing required keys: userName'])
65 end
66
67 context 'with an optional attribute behind a $ref' do
68 let(:schema) do
69 {
70 'type' => 'object',
71 'properties' => { 'meta' => { '$ref' => '#/$defs/meta' } },
72 '$defs' => {
73 'meta' => {
74 'type' => 'object',
75 'properties' => { 'version' => { 'type' => 'string' } }
76 }
77 }
78 }
79 end
80
81 it 'reports only the error the server actually made' do
82 errors = described_class.errors_for(schema, { meta: { version: 1 } })
83
84 expect(errors).to eql(
85 ["property '/meta/version' is not of type: string"]
86 )
87 end
88 end
89
90 it 'accepts a declared attribute the server spelled differently' do
91 errors = described_class.errors_for(schema, { USERNAME: 'bjensen' })
92
93 expect(errors).to eql([])
94 end
95
96 it 'reports the canonical name when a differently spelled value is wrong' do
97 errors = described_class.errors_for(schema, { USERNAME: 1 })
98
99 expect(errors).to eql(["property '/userName' is not of type: string"])
100 end
101
102 it 'returns a readable error for an undeclared property' do
103 errors = described_class.errors_for(schema, { userName: 'bjensen', extra: true })
104
105 expect(errors).to eql(["property '/extra' is invalid: error_type=schema"])
106 end
107 end
108end