workos 0.10.0 → 1.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/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/.semaphore/semaphore.yml +8 -2
- data/Gemfile.lock +49 -36
- data/LICENSE +1 -1
- data/README.md +13 -230
- data/lib/workos/client.rb +21 -4
- data/lib/workos/connection.rb +12 -1
- data/lib/workos/directory.rb +53 -0
- data/lib/workos/directory_group.rb +44 -0
- data/lib/workos/directory_sync.rb +63 -7
- data/lib/workos/directory_user.rb +63 -0
- data/lib/workos/organizations.rb +150 -0
- data/lib/workos/passwordless.rb +4 -0
- data/lib/workos/portal.rb +1 -81
- data/lib/workos/profile.rb +1 -2
- data/lib/workos/profile_and_token.rb +28 -0
- data/lib/workos/sso.rb +39 -104
- data/lib/workos/types/connection_struct.rb +3 -0
- data/lib/workos/types/directory_group_struct.rb +13 -0
- data/lib/workos/types/directory_struct.rb +16 -0
- data/lib/workos/types/directory_user_struct.rb +19 -0
- data/lib/workos/types/intent_enum.rb +1 -0
- data/lib/workos/types.rb +3 -0
- data/lib/workos/version.rb +1 -1
- data/lib/workos.rb +5 -0
- data/sorbet/rbi/gems/addressable.rbi +199 -0
- data/sorbet/rbi/gems/ast.rbi +49 -0
- data/sorbet/rbi/gems/codecov.rbi +37 -0
- data/sorbet/rbi/gems/crack.rbi +62 -0
- data/sorbet/rbi/gems/docile.rbi +36 -0
- data/sorbet/rbi/gems/hashdiff.rbi +66 -0
- data/sorbet/rbi/gems/parallel.rbi +83 -0
- data/sorbet/rbi/gems/parser.rbi +1429 -0
- data/sorbet/rbi/gems/public_suffix.rbi +104 -0
- data/sorbet/rbi/gems/rainbow.rbi +118 -0
- data/sorbet/rbi/gems/rake.rbi +644 -0
- data/sorbet/rbi/gems/regexp_parser.rbi +926 -0
- data/sorbet/rbi/gems/rexml.rbi +628 -0
- data/sorbet/rbi/gems/rspec-core.rbi +1898 -0
- data/sorbet/rbi/gems/rspec-expectations.rbi +1127 -0
- data/sorbet/rbi/gems/rspec-mocks.rbi +1099 -0
- data/sorbet/rbi/gems/rspec-support.rbi +280 -0
- data/sorbet/rbi/gems/rspec.rbi +15 -0
- data/sorbet/rbi/gems/rubocop-ast.rbi +1355 -0
- data/sorbet/rbi/gems/rubocop.rbi +7253 -0
- data/sorbet/rbi/gems/ruby-progressbar.rbi +304 -0
- data/sorbet/rbi/gems/simplecov-html.rbi +35 -0
- data/sorbet/rbi/gems/simplecov.rbi +406 -0
- data/sorbet/rbi/gems/unicode-display_width.rbi +17 -0
- data/sorbet/rbi/gems/vcr.rbi +572 -0
- data/sorbet/rbi/gems/webmock.rbi +556 -0
- data/sorbet/rbi/gems/yard.rbi +1165 -0
- data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +645 -0
- data/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi +1891 -0
- data/sorbet/rbi/sorbet-typed/lib/rubocop/~>0.85/rubocop.rbi +2072 -0
- data/sorbet/rbi/sorbet-typed/lib/yard/all/yard.rbi +1214 -0
- data/sorbet/rbi/todo.rbi +1 -3
- data/spec/lib/workos/audit_trail_spec.rb +0 -8
- data/spec/lib/workos/directory_sync_spec.rb +347 -40
- data/spec/lib/workos/organizations_spec.rb +164 -0
- data/spec/lib/workos/passwordless_spec.rb +0 -8
- data/spec/lib/workos/portal_spec.rb +17 -123
- data/spec/lib/workos/sso_spec.rb +144 -176
- data/spec/spec_helper.rb +2 -1
- data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/{sso/list_connections.yml → directory_sync/list_directories/with_after.yml} +7 -7
- data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_limit_param.yml → directory_sync/list_directories/with_before.yml} +8 -8
- data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_connection_type_param.yml → directory_sync/list_directories/with_domain.yml} +11 -10
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_limit.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_directories.yml → list_directories/with_no_options.yml} +1 -1
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +76 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +78 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_groups.yml → list_groups/with_no_options.yml} +16 -6
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +86 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +75 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +93 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +76 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +75 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_users.yml → list_users/with_no_options.yml} +16 -6
- data/spec/support/fixtures/vcr_cassettes/organization/get.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update_invalid.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/{generate_link.yml → generate_link_sso.yml} +1 -1
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/sso/{list_connections_with_domain_param.yml → list_connections/with_domain.yml} +6 -6
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/sso/{list_connections_with_before_param.yml → list_connections/with_organization_id.yml} +7 -8
- data/workos.gemspec +2 -0
- metadata +113 -44
- data/sorbet/rbi/hidden-definitions/errors.txt +0 -24896
- data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -38411
- data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +0 -8684
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +0 -4222
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +0 -111
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +0 -543
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories_with_domain_param.yml +0 -63
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups_with_directory_param.yml +0 -62
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users_with_directory_param.yml +0 -62
- data/spec/support/fixtures/vcr_cassettes/sso/create_connection_with_invalid_source.yml +0 -58
- data/spec/support/fixtures/vcr_cassettes/sso/create_connection_with_valid_source.yml +0 -63
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_after_param.yml +0 -72
|
@@ -2,56 +2,30 @@
|
|
|
2
2
|
# typed: false
|
|
3
3
|
|
|
4
4
|
describe WorkOS::Portal do
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
after :all do
|
|
10
|
-
WorkOS.key = nil
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
describe '.create_organization' do
|
|
14
|
-
context 'with valid payload' do
|
|
15
|
-
it 'creates an organization' do
|
|
16
|
-
VCR.use_cassette 'organization/create' do
|
|
17
|
-
organization = described_class.create_organization(
|
|
18
|
-
domains: ['example.com'],
|
|
19
|
-
name: 'Test Organization',
|
|
20
|
-
)
|
|
5
|
+
describe '.generate_link' do
|
|
6
|
+
let(:organization) { 'org_01EHQMYV6MBK39QC5PZXHY59C3' }
|
|
21
7
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
describe 'with a valid organization' do
|
|
9
|
+
context 'with the sso intent' do
|
|
10
|
+
it 'returns an Admin Portal link' do
|
|
11
|
+
VCR.use_cassette 'portal/generate_link_sso' do
|
|
12
|
+
portal_link = described_class.generate_link(
|
|
13
|
+
intent: 'sso',
|
|
14
|
+
organization: organization,
|
|
15
|
+
)
|
|
28
16
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
VCR.use_cassette 'organization/create_invalid' do
|
|
32
|
-
expect do
|
|
33
|
-
described_class.create_organization(
|
|
34
|
-
domains: ['example.com'],
|
|
35
|
-
name: 'Test Organization 2',
|
|
17
|
+
expect(portal_link).to eq(
|
|
18
|
+
'https://id.workos.com/portal/launch?secret=secret',
|
|
36
19
|
)
|
|
37
|
-
end
|
|
38
|
-
WorkOS::APIError,
|
|
39
|
-
/An Organization with the domain example.com already exists/,
|
|
40
|
-
)
|
|
20
|
+
end
|
|
41
21
|
end
|
|
42
22
|
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
23
|
|
|
46
|
-
|
|
47
|
-
let(:organization) { 'org_01EHQMYV6MBK39QC5PZXHY59C3' }
|
|
48
|
-
|
|
49
|
-
describe 'with a valid organization' do
|
|
50
|
-
describe 'with the minimal params' do
|
|
24
|
+
describe 'with the dsync intent' do
|
|
51
25
|
it 'returns an Admin Portal link' do
|
|
52
|
-
VCR.use_cassette 'portal/
|
|
26
|
+
VCR.use_cassette 'portal/generate_link_dsync' do
|
|
53
27
|
portal_link = described_class.generate_link(
|
|
54
|
-
intent: '
|
|
28
|
+
intent: 'dsync',
|
|
55
29
|
organization: organization,
|
|
56
30
|
)
|
|
57
31
|
|
|
@@ -88,89 +62,9 @@ describe WorkOS::Portal do
|
|
|
88
62
|
)
|
|
89
63
|
end.to raise_error(
|
|
90
64
|
ArgumentError,
|
|
91
|
-
|
|
65
|
+
/bogus-intent is not a valid value/,
|
|
92
66
|
)
|
|
93
67
|
end
|
|
94
68
|
end
|
|
95
69
|
end
|
|
96
|
-
|
|
97
|
-
describe '.list_organizations' do
|
|
98
|
-
context 'with no options' do
|
|
99
|
-
it 'returns organizations and metadata' do
|
|
100
|
-
expected_metadata = {
|
|
101
|
-
'after' => nil,
|
|
102
|
-
'before' => 'before-id',
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
VCR.use_cassette 'organization/list' do
|
|
106
|
-
organizations = described_class.list_organizations
|
|
107
|
-
|
|
108
|
-
expect(organizations.data.size).to eq(7)
|
|
109
|
-
expect(organizations.list_metadata).to eq(expected_metadata)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
context 'with the before option' do
|
|
115
|
-
it 'forms the proper request to the API' do
|
|
116
|
-
request_args = [
|
|
117
|
-
'/organizations?before=before-id',
|
|
118
|
-
'Content-Type' => 'application/json'
|
|
119
|
-
]
|
|
120
|
-
|
|
121
|
-
expected_request = Net::HTTP::Get.new(*request_args)
|
|
122
|
-
|
|
123
|
-
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
124
|
-
and_return(expected_request)
|
|
125
|
-
|
|
126
|
-
VCR.use_cassette 'organization/list', match_requests_on: [:path] do
|
|
127
|
-
organizations = described_class.list_organizations(
|
|
128
|
-
before: 'before-id',
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
expect(organizations.data.size).to eq(7)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
context 'with the after option' do
|
|
137
|
-
it 'forms the proper request to the API' do
|
|
138
|
-
request_args = [
|
|
139
|
-
'/organizations?after=after-id',
|
|
140
|
-
'Content-Type' => 'application/json'
|
|
141
|
-
]
|
|
142
|
-
|
|
143
|
-
expected_request = Net::HTTP::Get.new(*request_args)
|
|
144
|
-
|
|
145
|
-
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
146
|
-
and_return(expected_request)
|
|
147
|
-
|
|
148
|
-
VCR.use_cassette 'organization/list', match_requests_on: [:path] do
|
|
149
|
-
organizations = described_class.list_organizations(after: 'after-id')
|
|
150
|
-
|
|
151
|
-
expect(organizations.data.size).to eq(7)
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
context 'with the limit option' do
|
|
157
|
-
it 'forms the proper request to the API' do
|
|
158
|
-
request_args = [
|
|
159
|
-
'/organizations?limit=10',
|
|
160
|
-
'Content-Type' => 'application/json'
|
|
161
|
-
]
|
|
162
|
-
|
|
163
|
-
expected_request = Net::HTTP::Get.new(*request_args)
|
|
164
|
-
|
|
165
|
-
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
166
|
-
and_return(expected_request)
|
|
167
|
-
|
|
168
|
-
VCR.use_cassette 'organization/list', match_requests_on: [:path] do
|
|
169
|
-
organizations = described_class.list_organizations(limit: 10)
|
|
170
|
-
|
|
171
|
-
expect(organizations.data.size).to eq(7)
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
70
|
end
|
data/spec/lib/workos/sso_spec.rb
CHANGED
|
@@ -73,9 +73,10 @@ describe WorkOS::SSO do
|
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
context 'with
|
|
76
|
+
context 'with a connection' do
|
|
77
77
|
let(:args) do
|
|
78
78
|
{
|
|
79
|
+
connection: 'connection_123',
|
|
79
80
|
client_id: 'workos-proj-123',
|
|
80
81
|
redirect_uri: 'foo.com/auth/callback',
|
|
81
82
|
state: {
|
|
@@ -83,20 +84,32 @@ describe WorkOS::SSO do
|
|
|
83
84
|
}.to_s,
|
|
84
85
|
}
|
|
85
86
|
end
|
|
86
|
-
it '
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
it 'returns a valid URL' do
|
|
88
|
+
authorization_url = described_class.authorization_url(**args)
|
|
89
|
+
|
|
90
|
+
expect(URI.parse(authorization_url)).to be_a URI
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'returns the expected hostname' do
|
|
94
|
+
authorization_url = described_class.authorization_url(**args)
|
|
95
|
+
|
|
96
|
+
expect(URI.parse(authorization_url).host).to eq(WorkOS::API_HOSTNAME)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'returns the expected query string' do
|
|
100
|
+
authorization_url = described_class.authorization_url(**args)
|
|
101
|
+
|
|
102
|
+
expect(URI.parse(authorization_url).query).to eq(
|
|
103
|
+
'client_id=workos-proj-123&redirect_uri=foo.com%2Fauth%2Fcallback' \
|
|
104
|
+
'&response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdashboard%2F' \
|
|
105
|
+
'edit%22%7D&connection=connection_123',
|
|
92
106
|
)
|
|
93
107
|
end
|
|
94
108
|
end
|
|
95
109
|
|
|
96
|
-
context 'with
|
|
110
|
+
context 'with neither connection, domain, or provider' do
|
|
97
111
|
let(:args) do
|
|
98
112
|
{
|
|
99
|
-
provider: 'Okta',
|
|
100
113
|
client_id: 'workos-proj-123',
|
|
101
114
|
redirect_uri: 'foo.com/auth/callback',
|
|
102
115
|
state: {
|
|
@@ -109,60 +122,34 @@ describe WorkOS::SSO do
|
|
|
109
122
|
described_class.authorization_url(**args)
|
|
110
123
|
end.to raise_error(
|
|
111
124
|
ArgumentError,
|
|
112
|
-
'
|
|
125
|
+
'Either connection, domain, or provider is required.',
|
|
113
126
|
)
|
|
114
127
|
end
|
|
115
128
|
end
|
|
116
129
|
|
|
117
|
-
context '
|
|
130
|
+
context 'with an invalid provider' do
|
|
118
131
|
let(:args) do
|
|
119
132
|
{
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
provider: 'Okta',
|
|
134
|
+
client_id: 'workos-proj-123',
|
|
122
135
|
redirect_uri: 'foo.com/auth/callback',
|
|
123
136
|
state: {
|
|
124
137
|
next_page: '/dashboard/edit',
|
|
125
138
|
}.to_s,
|
|
126
139
|
}
|
|
127
140
|
end
|
|
128
|
-
it 'raises
|
|
141
|
+
it 'raises an error' do
|
|
129
142
|
expect do
|
|
130
143
|
described_class.authorization_url(**args)
|
|
131
|
-
end.to
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
).to_stderr
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it 'returns a valid URL' do
|
|
138
|
-
authorization_url = described_class.authorization_url(**args)
|
|
139
|
-
|
|
140
|
-
expect(URI.parse(authorization_url)).to be_a URI
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
it 'returns the expected hostname' do
|
|
144
|
-
authorization_url = described_class.authorization_url(**args)
|
|
145
|
-
|
|
146
|
-
expect(URI.parse(authorization_url).host).to eq(WorkOS::API_HOSTNAME)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
it 'returns the expected query string' do
|
|
150
|
-
authorization_url = described_class.authorization_url(**args)
|
|
151
|
-
|
|
152
|
-
expect(URI.parse(authorization_url).query).to eq(
|
|
153
|
-
'client_id=workos-proj-123&redirect_uri=foo.com%2Fauth%2Fcallback' \
|
|
154
|
-
'&response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdashboard%2F' \
|
|
155
|
-
'edit%22%7D&domain=foo.com',
|
|
144
|
+
end.to raise_error(
|
|
145
|
+
ArgumentError,
|
|
146
|
+
'Okta is not a valid value. `provider` must be in ["GoogleOAuth"]',
|
|
156
147
|
)
|
|
157
148
|
end
|
|
158
149
|
end
|
|
159
150
|
end
|
|
160
151
|
|
|
161
|
-
describe '.
|
|
162
|
-
before do
|
|
163
|
-
WorkOS.key = 'api-key'
|
|
164
|
-
end
|
|
165
|
-
|
|
152
|
+
describe '.profile_and_token' do
|
|
166
153
|
let(:args) do
|
|
167
154
|
{
|
|
168
155
|
code: SecureRandom.hex(10),
|
|
@@ -195,15 +182,15 @@ describe WorkOS::SSO do
|
|
|
195
182
|
end
|
|
196
183
|
|
|
197
184
|
it 'includes the SDK Version header' do
|
|
198
|
-
described_class.
|
|
185
|
+
described_class.profile_and_token(**args)
|
|
199
186
|
|
|
200
187
|
expect(a_request(:post, 'https://api.workos.com/sso/token').
|
|
201
188
|
with(headers: headers, body: request_body)).to have_been_made
|
|
202
189
|
end
|
|
203
190
|
|
|
204
|
-
it 'returns a WorkOS::
|
|
205
|
-
|
|
206
|
-
expect(
|
|
191
|
+
it 'returns a WorkOS::ProfileAndToken' do
|
|
192
|
+
profile_and_token = described_class.profile_and_token(**args)
|
|
193
|
+
expect(profile_and_token).to be_a(WorkOS::ProfileAndToken)
|
|
207
194
|
|
|
208
195
|
expectation = {
|
|
209
196
|
connection_id: 'conn_01EMH8WAK20T42N2NBMNBCYHAG',
|
|
@@ -222,7 +209,8 @@ describe WorkOS::SSO do
|
|
|
222
209
|
},
|
|
223
210
|
}
|
|
224
211
|
|
|
225
|
-
expect(
|
|
212
|
+
expect(profile_and_token.access_token).to eq('01DVX6QBS3EG6FHY2ESAA5Q65X')
|
|
213
|
+
expect(profile_and_token.profile.to_json).to eq(expectation)
|
|
226
214
|
end
|
|
227
215
|
end
|
|
228
216
|
|
|
@@ -239,7 +227,7 @@ describe WorkOS::SSO do
|
|
|
239
227
|
|
|
240
228
|
it 'raises an exception with request ID' do
|
|
241
229
|
expect do
|
|
242
|
-
described_class.
|
|
230
|
+
described_class.profile_and_token(**args)
|
|
243
231
|
end.to raise_error(
|
|
244
232
|
WorkOS::APIError,
|
|
245
233
|
'some error message - request ID: request-id',
|
|
@@ -263,7 +251,7 @@ describe WorkOS::SSO do
|
|
|
263
251
|
|
|
264
252
|
it 'raises an exception' do
|
|
265
253
|
expect do
|
|
266
|
-
described_class.
|
|
254
|
+
described_class.profile_and_token(**args)
|
|
267
255
|
end.to raise_error(
|
|
268
256
|
WorkOS::APIError,
|
|
269
257
|
"The code '01DVX3C5Z367SFHR8QNDMK7V24'" \
|
|
@@ -273,173 +261,161 @@ describe WorkOS::SSO do
|
|
|
273
261
|
end
|
|
274
262
|
end
|
|
275
263
|
|
|
276
|
-
describe '.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
end
|
|
264
|
+
describe '.list_connections' do
|
|
265
|
+
context 'with no options' do
|
|
266
|
+
it 'returns connections and metadata' do
|
|
267
|
+
expected_metadata = {
|
|
268
|
+
'after' => nil,
|
|
269
|
+
'before' => 'before_id',
|
|
270
|
+
}
|
|
284
271
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
VCR.use_cassette('sso/create_connection_with_valid_source') do
|
|
288
|
-
connection = WorkOS::SSO.create_connection(
|
|
289
|
-
source: 'draft_conn_01E6PK87QP6NQ29RRX0G100YGV',
|
|
290
|
-
)
|
|
272
|
+
VCR.use_cassette 'sso/list_connections/with_no_options' do
|
|
273
|
+
connections = described_class.list_connections
|
|
291
274
|
|
|
292
|
-
expect(
|
|
293
|
-
expect(
|
|
294
|
-
expect(connection.name).to eq('Foo Corp')
|
|
295
|
-
expect(connection.domains.first[:domain]).to eq('example.com')
|
|
275
|
+
expect(connections.data.size).to eq(3)
|
|
276
|
+
expect(connections.list_metadata).to eq(expected_metadata)
|
|
296
277
|
end
|
|
297
278
|
end
|
|
298
279
|
end
|
|
299
280
|
|
|
300
|
-
context 'with
|
|
301
|
-
it '
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
WorkOS::APIError,
|
|
307
|
-
'Status 404, Not Found - request ID: ',
|
|
308
|
-
)
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
describe '.promote_draft_connection' do
|
|
315
|
-
before(:all) do
|
|
316
|
-
WorkOS.key = 'key'
|
|
317
|
-
end
|
|
281
|
+
context 'with connection_type option' do
|
|
282
|
+
it 'forms the proper request to the API' do
|
|
283
|
+
request_args = [
|
|
284
|
+
'/connections?connection_type=OktaSAML',
|
|
285
|
+
'Content-Type' => 'application/json'
|
|
286
|
+
]
|
|
318
287
|
|
|
319
|
-
|
|
320
|
-
WorkOS.key = nil
|
|
321
|
-
end
|
|
288
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
|
322
289
|
|
|
323
|
-
|
|
324
|
-
|
|
290
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
291
|
+
and_return(expected_request)
|
|
325
292
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
"https://api.workos.com/draft_connections/#{token}/activate",
|
|
331
|
-
).to_return(status: 200)
|
|
332
|
-
end
|
|
333
|
-
it 'returns true' do
|
|
334
|
-
response = described_class.promote_draft_connection(
|
|
335
|
-
token: token,
|
|
336
|
-
)
|
|
293
|
+
VCR.use_cassette 'sso/list_connections/with_connection_type' do
|
|
294
|
+
connections = described_class.list_connections(
|
|
295
|
+
connection_type: 'OktaSAML',
|
|
296
|
+
)
|
|
337
297
|
|
|
338
|
-
|
|
298
|
+
expect(connections.data.size).to eq(3)
|
|
299
|
+
expect(connections.data.first.connection_type).to eq('OktaSAML')
|
|
300
|
+
end
|
|
339
301
|
end
|
|
340
302
|
end
|
|
341
303
|
|
|
342
|
-
context 'with
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
end
|
|
349
|
-
it 'returns true' do
|
|
350
|
-
response = described_class.promote_draft_connection(
|
|
351
|
-
token: token,
|
|
352
|
-
)
|
|
304
|
+
context 'with domain option' do
|
|
305
|
+
it 'forms the proper request to the API' do
|
|
306
|
+
request_args = [
|
|
307
|
+
'/connections?domain=foo-corp.com',
|
|
308
|
+
'Content-Type' => 'application/json'
|
|
309
|
+
]
|
|
353
310
|
|
|
354
|
-
|
|
355
|
-
end
|
|
356
|
-
end
|
|
357
|
-
end
|
|
311
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
|
358
312
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
WorkOS.key = 'key'
|
|
362
|
-
end
|
|
313
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
314
|
+
and_return(expected_request)
|
|
363
315
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
316
|
+
VCR.use_cassette 'sso/list_connections/with_domain' do
|
|
317
|
+
connections = described_class.list_connections(
|
|
318
|
+
domain: 'foo-corp.com',
|
|
319
|
+
)
|
|
367
320
|
|
|
368
|
-
|
|
369
|
-
it 'returns connections' do
|
|
370
|
-
VCR.use_cassette('sso/list_connections') do
|
|
371
|
-
connections = WorkOS::SSO.list_connections
|
|
372
|
-
expect(connections.size).to eq(1)
|
|
321
|
+
expect(connections.data.size).to eq(1)
|
|
373
322
|
end
|
|
374
323
|
end
|
|
375
324
|
end
|
|
376
325
|
|
|
377
|
-
context 'with
|
|
378
|
-
it '
|
|
379
|
-
|
|
380
|
-
connections
|
|
381
|
-
|
|
326
|
+
context 'with organization_id option' do
|
|
327
|
+
it 'forms the proper request to the API' do
|
|
328
|
+
request_args = [
|
|
329
|
+
'/connections?organization_id=org_01EGS4P7QR31EZ4YWD1Z1XA176',
|
|
330
|
+
'Content-Type' => 'application/json'
|
|
331
|
+
]
|
|
332
|
+
|
|
333
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
|
334
|
+
|
|
335
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
336
|
+
and_return(expected_request)
|
|
337
|
+
|
|
338
|
+
VCR.use_cassette 'sso/list_connections/with_organization_id' do
|
|
339
|
+
connections = described_class.list_connections(
|
|
340
|
+
organization_id: 'org_01EGS4P7QR31EZ4YWD1Z1XA176',
|
|
382
341
|
)
|
|
383
|
-
expect(connections.first['connection_type']).to eq('OktaSAML')
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
end
|
|
387
342
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
connections = WorkOS::SSO.list_connections(
|
|
392
|
-
domain: 'foo-corp.com',
|
|
343
|
+
expect(connections.data.size).to eq(1)
|
|
344
|
+
expect(connections.data.first.organization_id).to eq(
|
|
345
|
+
'org_01EGS4P7QR31EZ4YWD1Z1XA176',
|
|
393
346
|
)
|
|
394
|
-
domains = connections.first['domains']
|
|
395
|
-
expect(domains.first['domain']).to eq('foo-corp.com')
|
|
396
347
|
end
|
|
397
348
|
end
|
|
398
349
|
end
|
|
399
350
|
|
|
400
351
|
context 'with limit option' do
|
|
401
|
-
it '
|
|
402
|
-
|
|
403
|
-
connections
|
|
404
|
-
|
|
352
|
+
it 'forms the proper request to the API' do
|
|
353
|
+
request_args = [
|
|
354
|
+
'/connections?limit=2',
|
|
355
|
+
'Content-Type' => 'application/json'
|
|
356
|
+
]
|
|
357
|
+
|
|
358
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
|
359
|
+
|
|
360
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
361
|
+
and_return(expected_request)
|
|
362
|
+
|
|
363
|
+
VCR.use_cassette 'sso/list_connections/with_limit' do
|
|
364
|
+
connections = described_class.list_connections(
|
|
365
|
+
limit: 2,
|
|
405
366
|
)
|
|
406
|
-
|
|
367
|
+
|
|
368
|
+
expect(connections.data.size).to eq(2)
|
|
407
369
|
end
|
|
408
370
|
end
|
|
409
371
|
end
|
|
410
372
|
|
|
411
373
|
context 'with before option' do
|
|
412
|
-
it '
|
|
413
|
-
|
|
414
|
-
connections
|
|
374
|
+
it 'forms the proper request to the API' do
|
|
375
|
+
request_args = [
|
|
376
|
+
'/connections?before=conn_01EQKPMQAPV02H270HKVNS4CTA',
|
|
377
|
+
'Content-Type' => 'application/json'
|
|
378
|
+
]
|
|
379
|
+
|
|
380
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
|
381
|
+
|
|
382
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
383
|
+
and_return(expected_request)
|
|
384
|
+
|
|
385
|
+
VCR.use_cassette 'sso/list_connections/with_before' do
|
|
386
|
+
connections = described_class.list_connections(
|
|
415
387
|
before: 'conn_01EQKPMQAPV02H270HKVNS4CTA',
|
|
416
388
|
)
|
|
417
|
-
|
|
389
|
+
|
|
390
|
+
expect(connections.data.size).to eq(3)
|
|
418
391
|
end
|
|
419
392
|
end
|
|
420
393
|
end
|
|
421
394
|
|
|
422
395
|
context 'with after option' do
|
|
423
|
-
it '
|
|
424
|
-
|
|
425
|
-
connections
|
|
396
|
+
it 'forms the proper request to the API' do
|
|
397
|
+
request_args = [
|
|
398
|
+
'/connections?after=conn_01EQKPMQAPV02H270HKVNS4CTA',
|
|
399
|
+
'Content-Type' => 'application/json'
|
|
400
|
+
]
|
|
401
|
+
|
|
402
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
|
403
|
+
|
|
404
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
|
405
|
+
and_return(expected_request)
|
|
406
|
+
|
|
407
|
+
VCR.use_cassette 'sso/list_connections/with_after' do
|
|
408
|
+
connections = described_class.list_connections(
|
|
426
409
|
after: 'conn_01EQKPMQAPV02H270HKVNS4CTA',
|
|
427
410
|
)
|
|
428
|
-
|
|
411
|
+
|
|
412
|
+
expect(connections.data.size).to eq(3)
|
|
429
413
|
end
|
|
430
414
|
end
|
|
431
415
|
end
|
|
432
416
|
end
|
|
433
417
|
|
|
434
418
|
describe '.get_connection' do
|
|
435
|
-
before(:all) do
|
|
436
|
-
WorkOS.key = 'key'
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
after(:all) do
|
|
440
|
-
WorkOS.key = nil
|
|
441
|
-
end
|
|
442
|
-
|
|
443
419
|
context 'with a valid id' do
|
|
444
420
|
it 'gets the connection details' do
|
|
445
421
|
VCR.use_cassette('sso/get_connection_with_valid_id') do
|
|
@@ -470,14 +446,6 @@ describe WorkOS::SSO do
|
|
|
470
446
|
end
|
|
471
447
|
|
|
472
448
|
describe '.delete_connection' do
|
|
473
|
-
before(:all) do
|
|
474
|
-
WorkOS.key = 'key'
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
after(:all) do
|
|
478
|
-
WorkOS.key = nil
|
|
479
|
-
end
|
|
480
|
-
|
|
481
449
|
context 'with a valid id' do
|
|
482
450
|
it 'returns true' do
|
|
483
451
|
VCR.use_cassette('sso/delete_connection_with_valid_id') do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# typed:
|
|
2
|
+
# typed: false
|
|
3
3
|
|
|
4
4
|
require 'simplecov'
|
|
5
5
|
SimpleCov.start
|
|
@@ -48,5 +48,6 @@ RSpec.configure do |config|
|
|
|
48
48
|
end
|
|
49
49
|
end)
|
|
50
50
|
|
|
51
|
+
config.before(:all) { WorkOS.key ||= '' }
|
|
51
52
|
config.before(:each) { VCR.turn_on! }
|
|
52
53
|
end
|