workos 0.10.2 → 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.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.ruby-version +1 -1
  4. data/.semaphore/semaphore.yml +8 -2
  5. data/Gemfile.lock +49 -36
  6. data/LICENSE +1 -1
  7. data/README.md +13 -230
  8. data/lib/workos.rb +5 -0
  9. data/lib/workos/client.rb +21 -4
  10. data/lib/workos/connection.rb +12 -1
  11. data/lib/workos/directory.rb +53 -0
  12. data/lib/workos/directory_group.rb +44 -0
  13. data/lib/workos/directory_sync.rb +63 -7
  14. data/lib/workos/directory_user.rb +63 -0
  15. data/lib/workos/organizations.rb +150 -0
  16. data/lib/workos/passwordless.rb +4 -0
  17. data/lib/workos/portal.rb +0 -80
  18. data/lib/workos/profile.rb +1 -2
  19. data/lib/workos/profile_and_token.rb +28 -0
  20. data/lib/workos/sso.rb +37 -104
  21. data/lib/workos/types.rb +3 -0
  22. data/lib/workos/types/connection_struct.rb +3 -0
  23. data/lib/workos/types/directory_group_struct.rb +13 -0
  24. data/lib/workos/types/directory_struct.rb +16 -0
  25. data/lib/workos/types/directory_user_struct.rb +19 -0
  26. data/lib/workos/version.rb +1 -1
  27. data/sorbet/rbi/gems/addressable.rbi +199 -0
  28. data/sorbet/rbi/gems/ast.rbi +49 -0
  29. data/sorbet/rbi/gems/codecov.rbi +37 -0
  30. data/sorbet/rbi/gems/crack.rbi +62 -0
  31. data/sorbet/rbi/gems/docile.rbi +36 -0
  32. data/sorbet/rbi/gems/hashdiff.rbi +66 -0
  33. data/sorbet/rbi/gems/parallel.rbi +83 -0
  34. data/sorbet/rbi/gems/parser.rbi +1429 -0
  35. data/sorbet/rbi/gems/public_suffix.rbi +104 -0
  36. data/sorbet/rbi/gems/rainbow.rbi +118 -0
  37. data/sorbet/rbi/gems/rake.rbi +644 -0
  38. data/sorbet/rbi/gems/regexp_parser.rbi +926 -0
  39. data/sorbet/rbi/gems/rexml.rbi +628 -0
  40. data/sorbet/rbi/gems/rspec-core.rbi +1898 -0
  41. data/sorbet/rbi/gems/rspec-expectations.rbi +1127 -0
  42. data/sorbet/rbi/gems/rspec-mocks.rbi +1099 -0
  43. data/sorbet/rbi/gems/rspec-support.rbi +280 -0
  44. data/sorbet/rbi/gems/rspec.rbi +15 -0
  45. data/sorbet/rbi/gems/rubocop-ast.rbi +1355 -0
  46. data/sorbet/rbi/gems/rubocop.rbi +7253 -0
  47. data/sorbet/rbi/gems/ruby-progressbar.rbi +304 -0
  48. data/sorbet/rbi/gems/simplecov-html.rbi +35 -0
  49. data/sorbet/rbi/gems/simplecov.rbi +406 -0
  50. data/sorbet/rbi/gems/unicode-display_width.rbi +17 -0
  51. data/sorbet/rbi/gems/vcr.rbi +572 -0
  52. data/sorbet/rbi/gems/webmock.rbi +556 -0
  53. data/sorbet/rbi/gems/yard.rbi +1165 -0
  54. data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +645 -0
  55. data/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi +1891 -0
  56. data/sorbet/rbi/sorbet-typed/lib/rubocop/~>0.85/rubocop.rbi +2072 -0
  57. data/sorbet/rbi/sorbet-typed/lib/yard/all/yard.rbi +1214 -0
  58. data/sorbet/rbi/todo.rbi +1 -3
  59. data/spec/lib/workos/audit_trail_spec.rb +0 -8
  60. data/spec/lib/workos/directory_sync_spec.rb +347 -40
  61. data/spec/lib/workos/organizations_spec.rb +164 -0
  62. data/spec/lib/workos/passwordless_spec.rb +0 -8
  63. data/spec/lib/workos/portal_spec.rb +0 -121
  64. data/spec/lib/workos/sso_spec.rb +141 -187
  65. data/spec/spec_helper.rb +2 -1
  66. data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
  67. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections.yml → directory_sync/list_directories/with_after.yml} +7 -7
  68. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_limit_param.yml → directory_sync/list_directories/with_before.yml} +8 -8
  69. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_connection_type_param.yml → directory_sync/list_directories/with_domain.yml} +11 -10
  70. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_after_param.yml → directory_sync/list_directories/with_limit.yml} +12 -10
  71. data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_directories.yml → list_directories/with_no_options.yml} +1 -1
  72. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +73 -0
  73. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +76 -0
  74. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +74 -0
  75. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +78 -0
  76. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +74 -0
  77. data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_groups.yml → list_groups/with_no_options.yml} +16 -6
  78. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +72 -0
  79. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +86 -0
  80. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +75 -0
  81. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +93 -0
  82. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +76 -0
  83. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +75 -0
  84. data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_users.yml → list_users/with_no_options.yml} +16 -6
  85. data/spec/support/fixtures/vcr_cassettes/organization/get.yml +73 -0
  86. data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
  87. data/spec/support/fixtures/vcr_cassettes/organization/update.yml +73 -0
  88. data/spec/support/fixtures/vcr_cassettes/organization/update_invalid.yml +73 -0
  89. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +73 -0
  90. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +73 -0
  91. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +73 -0
  92. data/spec/support/fixtures/vcr_cassettes/sso/{list_connections_with_domain_param.yml → list_connections/with_domain.yml} +6 -6
  93. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +74 -0
  94. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +73 -0
  95. data/spec/support/fixtures/vcr_cassettes/sso/{list_connections_with_organization_id_param.yml → list_connections/with_organization_id.yml} +6 -6
  96. data/workos.gemspec +2 -0
  97. metadata +109 -44
  98. data/sorbet/rbi/hidden-definitions/errors.txt +0 -24896
  99. data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -38411
  100. data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +0 -8684
  101. data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +0 -4222
  102. data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +0 -111
  103. data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +0 -543
  104. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories_with_domain_param.yml +0 -63
  105. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups_with_directory_param.yml +0 -62
  106. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users_with_directory_param.yml +0 -62
  107. data/spec/support/fixtures/vcr_cassettes/sso/create_connection_with_invalid_source.yml +0 -58
  108. data/spec/support/fixtures/vcr_cassettes/sso/create_connection_with_valid_source.yml +0 -63
  109. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_before_param.yml +0 -73
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ describe WorkOS::Organizations do
5
+ describe '.create_organization' do
6
+ context 'with valid payload' do
7
+ it 'creates an organization' do
8
+ VCR.use_cassette 'organization/create' do
9
+ organization = described_class.create_organization(
10
+ domains: ['example.com'],
11
+ name: 'Test Organization',
12
+ )
13
+
14
+ expect(organization.id).to eq('org_01EHT88Z8J8795GZNQ4ZP1J81T')
15
+ expect(organization.name).to eq('Test Organization')
16
+ expect(organization.domains.first[:domain]).to eq('example.com')
17
+ end
18
+ end
19
+ end
20
+
21
+ context 'with an invalid payload' do
22
+ it 'returns an error' do
23
+ VCR.use_cassette 'organization/create_invalid' do
24
+ expect do
25
+ described_class.create_organization(
26
+ domains: ['example.com'],
27
+ name: 'Test Organization 2',
28
+ )
29
+ end.to raise_error(
30
+ WorkOS::APIError,
31
+ /An Organization with the domain example.com already exists/,
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '.list_organizations' do
39
+ context 'with no options' do
40
+ it 'returns organizations and metadata' do
41
+ expected_metadata = {
42
+ 'after' => nil,
43
+ 'before' => 'before-id',
44
+ }
45
+
46
+ VCR.use_cassette 'organization/list' do
47
+ organizations = described_class.list_organizations
48
+
49
+ expect(organizations.data.size).to eq(7)
50
+ expect(organizations.list_metadata).to eq(expected_metadata)
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'with the before option' do
56
+ it 'forms the proper request to the API' do
57
+ request_args = [
58
+ '/organizations?before=before-id',
59
+ 'Content-Type' => 'application/json'
60
+ ]
61
+
62
+ expected_request = Net::HTTP::Get.new(*request_args)
63
+
64
+ expect(Net::HTTP::Get).to receive(:new).with(*request_args).
65
+ and_return(expected_request)
66
+
67
+ VCR.use_cassette 'organization/list', match_requests_on: [:path] do
68
+ organizations = described_class.list_organizations(
69
+ before: 'before-id',
70
+ )
71
+
72
+ expect(organizations.data.size).to eq(7)
73
+ end
74
+ end
75
+ end
76
+
77
+ context 'with the after option' do
78
+ it 'forms the proper request to the API' do
79
+ request_args = [
80
+ '/organizations?after=after-id',
81
+ 'Content-Type' => 'application/json'
82
+ ]
83
+
84
+ expected_request = Net::HTTP::Get.new(*request_args)
85
+
86
+ expect(Net::HTTP::Get).to receive(:new).with(*request_args).
87
+ and_return(expected_request)
88
+
89
+ VCR.use_cassette 'organization/list', match_requests_on: [:path] do
90
+ organizations = described_class.list_organizations(after: 'after-id')
91
+
92
+ expect(organizations.data.size).to eq(7)
93
+ end
94
+ end
95
+ end
96
+
97
+ context 'with the limit option' do
98
+ it 'forms the proper request to the API' do
99
+ request_args = [
100
+ '/organizations?limit=10',
101
+ 'Content-Type' => 'application/json'
102
+ ]
103
+
104
+ expected_request = Net::HTTP::Get.new(*request_args)
105
+
106
+ expect(Net::HTTP::Get).to receive(:new).with(*request_args).
107
+ and_return(expected_request)
108
+
109
+ VCR.use_cassette 'organization/list', match_requests_on: [:path] do
110
+ organizations = described_class.list_organizations(limit: 10)
111
+
112
+ expect(organizations.data.size).to eq(7)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '.get_organization' do
119
+ context 'with a valid id' do
120
+ it 'gets the organization details' do
121
+ VCR.use_cassette('organization/get') do
122
+ organization = described_class.get_organization(
123
+ id: 'org_01EZDF20TZEJXKPSX2BJRN6TV6',
124
+ )
125
+
126
+ expect(organization.id).to eq('org_01EZDF20TZEJXKPSX2BJRN6TV6')
127
+ expect(organization.name).to eq('Foo Corp')
128
+ expect(organization.domains.first[:domain]).to eq('foo-corp.com')
129
+ end
130
+ end
131
+ end
132
+
133
+ context 'with an invalid id' do
134
+ it 'raises an error' do
135
+ VCR.use_cassette('organization/get_invalid') do
136
+ expect do
137
+ described_class.get_organization(id: 'invalid')
138
+ end.to raise_error(
139
+ WorkOS::APIError,
140
+ 'Status 404, Not Found - request ID: ',
141
+ )
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '.update_organization' do
148
+ context 'with valid payload' do
149
+ it 'creates an organization' do
150
+ VCR.use_cassette 'organization/update' do
151
+ organization = described_class.update_organization(
152
+ organization: 'org_01F29YJ068E52HGEB8ZQGC9MJG',
153
+ domains: ['example.me'],
154
+ name: 'Test Organization',
155
+ )
156
+
157
+ expect(organization.id).to eq('org_01F29YJ068E52HGEB8ZQGC9MJG')
158
+ expect(organization.name).to eq('Test Organization')
159
+ expect(organization.domains.first[:domain]).to eq('example.me')
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -2,14 +2,6 @@
2
2
  # typed: false
3
3
 
4
4
  describe WorkOS::Passwordless do
5
- before(:all) do
6
- WorkOS.key = 'key'
7
- end
8
-
9
- after(:all) do
10
- WorkOS.key = nil
11
- end
12
-
13
5
  describe '.create_session' do
14
6
  context 'with valid options payload' do
15
7
  let(:valid_options) do
@@ -2,47 +2,6 @@
2
2
  # typed: false
3
3
 
4
4
  describe WorkOS::Portal do
5
- before :all do
6
- WorkOS.key = 'test'
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
- )
21
-
22
- expect(organization.id).to eq('org_01EHT88Z8J8795GZNQ4ZP1J81T')
23
- expect(organization.name).to eq('Test Organization')
24
- expect(organization.domains.first[:domain]).to eq('example.com')
25
- end
26
- end
27
- end
28
-
29
- context 'with an invalid payload' do
30
- it 'returns an error' do
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',
36
- )
37
- end.to raise_error(
38
- WorkOS::APIError,
39
- /An Organization with the domain example.com already exists/,
40
- )
41
- end
42
- end
43
- end
44
- end
45
-
46
5
  describe '.generate_link' do
47
6
  let(:organization) { 'org_01EHQMYV6MBK39QC5PZXHY59C3' }
48
7
 
@@ -108,84 +67,4 @@ describe WorkOS::Portal do
108
67
  end
109
68
  end
110
69
  end
111
-
112
- describe '.list_organizations' do
113
- context 'with no options' do
114
- it 'returns organizations and metadata' do
115
- expected_metadata = {
116
- 'after' => nil,
117
- 'before' => 'before-id',
118
- }
119
-
120
- VCR.use_cassette 'organization/list' do
121
- organizations = described_class.list_organizations
122
-
123
- expect(organizations.data.size).to eq(7)
124
- expect(organizations.list_metadata).to eq(expected_metadata)
125
- end
126
- end
127
- end
128
-
129
- context 'with the before option' do
130
- it 'forms the proper request to the API' do
131
- request_args = [
132
- '/organizations?before=before-id',
133
- 'Content-Type' => 'application/json'
134
- ]
135
-
136
- expected_request = Net::HTTP::Get.new(*request_args)
137
-
138
- expect(Net::HTTP::Get).to receive(:new).with(*request_args).
139
- and_return(expected_request)
140
-
141
- VCR.use_cassette 'organization/list', match_requests_on: [:path] do
142
- organizations = described_class.list_organizations(
143
- before: 'before-id',
144
- )
145
-
146
- expect(organizations.data.size).to eq(7)
147
- end
148
- end
149
- end
150
-
151
- context 'with the after option' do
152
- it 'forms the proper request to the API' do
153
- request_args = [
154
- '/organizations?after=after-id',
155
- 'Content-Type' => 'application/json'
156
- ]
157
-
158
- expected_request = Net::HTTP::Get.new(*request_args)
159
-
160
- expect(Net::HTTP::Get).to receive(:new).with(*request_args).
161
- and_return(expected_request)
162
-
163
- VCR.use_cassette 'organization/list', match_requests_on: [:path] do
164
- organizations = described_class.list_organizations(after: 'after-id')
165
-
166
- expect(organizations.data.size).to eq(7)
167
- end
168
- end
169
- end
170
-
171
- context 'with the limit option' do
172
- it 'forms the proper request to the API' do
173
- request_args = [
174
- '/organizations?limit=10',
175
- 'Content-Type' => 'application/json'
176
- ]
177
-
178
- expected_request = Net::HTTP::Get.new(*request_args)
179
-
180
- expect(Net::HTTP::Get).to receive(:new).with(*request_args).
181
- and_return(expected_request)
182
-
183
- VCR.use_cassette 'organization/list', match_requests_on: [:path] do
184
- organizations = described_class.list_organizations(limit: 10)
185
-
186
- expect(organizations.data.size).to eq(7)
187
- end
188
- end
189
- end
190
- end
191
70
  end
@@ -73,9 +73,10 @@ describe WorkOS::SSO do
73
73
  end
74
74
  end
75
75
 
76
- context 'with neither domain or provider' do
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 'raises an error' do
87
- expect do
88
- described_class.authorization_url(**args)
89
- end.to raise_error(
90
- ArgumentError,
91
- 'Either domain or provider is required.',
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 an invalid provider' do
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
- 'Okta is not a valid value. `provider` must be in ["GoogleOAuth"]',
125
+ 'Either connection, domain, or provider is required.',
113
126
  )
114
127
  end
115
128
  end
116
129
 
117
- context 'passing the project_id' do
130
+ context 'with an invalid provider' do
118
131
  let(:args) do
119
132
  {
120
- domain: 'foo.com',
121
- project_id: 'workos-proj-123',
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 a deprecation warning' do
141
+ it 'raises an error' do
129
142
  expect do
130
143
  described_class.authorization_url(**args)
131
- end.to output(
132
- "[DEPRECATION] `project_id` is deprecated.
133
- Please use `client_id` instead.\n",
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 '.profile' do
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.profile(**args)
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::Profile' do
205
- profile = described_class.profile(**args)
206
- expect(profile).to be_a(WorkOS::Profile)
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(profile.to_json).to eq(expectation)
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.profile(**args)
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.profile(**args)
254
+ described_class.profile_and_token(**args)
267
255
  end.to raise_error(
268
256
  WorkOS::APIError,
269
257
  "The code '01DVX3C5Z367SFHR8QNDMK7V24'" \
@@ -273,138 +261,87 @@ describe WorkOS::SSO do
273
261
  end
274
262
  end
275
263
 
276
- describe '.create_connection' do
277
- before(:all) do
278
- WorkOS.key = 'key'
279
- end
280
-
281
- after(:all) do
282
- WorkOS.key = nil
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
- context 'with a valid source' do
286
- it 'creates a connection' do
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(connection.id).to eq('conn_01E4F9T2YWZFD218DN04KVFDSY')
293
- expect(connection.connection_type).to eq('GoogleOAuth')
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 an invalid source' do
301
- it 'raises an error' do
302
- VCR.use_cassette('sso/create_connection_with_invalid_source') do
303
- expect do
304
- WorkOS::SSO.create_connection(source: 'invalid')
305
- end.to raise_error(
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
318
-
319
- after(:all) do
320
- WorkOS.key = nil
321
- end
322
-
323
- let(:token) { 'draft_conn_id' }
324
- let(:client_id) { 'proj_0239u590h' }
325
-
326
- context 'with a valid request' do
327
- before do
328
- stub_request(
329
- :post,
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
- )
337
-
338
- expect(response).to be(true)
339
- end
340
- end
341
-
342
- context 'with an invalid request' do
343
- before do
344
- stub_request(
345
- :post,
346
- "https://api.workos.com/draft_connections/#{token}/activate",
347
- ).to_return(status: 403)
348
- end
349
- it 'returns true' do
350
- response = described_class.promote_draft_connection(
351
- token: token,
352
- )
353
-
354
- expect(response).to be(false)
355
- end
356
- end
357
- end
358
-
359
- describe '.list_connections' do
360
- before(:all) do
361
- WorkOS.key = 'key'
362
- 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
+ ]
363
287
 
364
- after(:all) do
365
- WorkOS.key = nil
366
- end
288
+ expected_request = Net::HTTP::Get.new(*request_args)
367
289
 
368
- context 'with no options' do
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)
373
- end
374
- end
375
- end
290
+ expect(Net::HTTP::Get).to receive(:new).with(*request_args).
291
+ and_return(expected_request)
376
292
 
377
- context 'with connection_type option' do
378
- it 'returns connections' do
379
- VCR.use_cassette('sso/list_connections_with_connection_type_param') do
380
- connections = WorkOS::SSO.list_connections(
293
+ VCR.use_cassette 'sso/list_connections/with_connection_type' do
294
+ connections = described_class.list_connections(
381
295
  connection_type: 'OktaSAML',
382
296
  )
383
- expect(connections.first['connection_type']).to eq('OktaSAML')
297
+
298
+ expect(connections.data.size).to eq(3)
299
+ expect(connections.data.first.connection_type).to eq('OktaSAML')
384
300
  end
385
301
  end
386
302
  end
387
303
 
388
304
  context 'with domain option' do
389
- it 'returns connections' do
390
- VCR.use_cassette('sso/list_connections_with_domain_param') do
391
- connections = WorkOS::SSO.list_connections(
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
+ ]
310
+
311
+ expected_request = Net::HTTP::Get.new(*request_args)
312
+
313
+ expect(Net::HTTP::Get).to receive(:new).with(*request_args).
314
+ and_return(expected_request)
315
+
316
+ VCR.use_cassette 'sso/list_connections/with_domain' do
317
+ connections = described_class.list_connections(
392
318
  domain: 'foo-corp.com',
393
319
  )
394
- domains = connections.first['domains']
395
- expect(domains.first['domain']).to eq('foo-corp.com')
320
+
321
+ expect(connections.data.size).to eq(1)
396
322
  end
397
323
  end
398
324
  end
399
325
 
400
326
  context 'with organization_id option' do
401
- it 'returns connections' do
402
- VCR.use_cassette('sso/list_connections_with_organization_id_param') do
403
- connections = WorkOS::SSO.list_connections(
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(
404
340
  organization_id: 'org_01EGS4P7QR31EZ4YWD1Z1XA176',
405
341
  )
406
- expect(connections.size).to eq(1)
407
- expect(connections.first['organization_id']).to eq(
342
+
343
+ expect(connections.data.size).to eq(1)
344
+ expect(connections.data.first.organization_id).to eq(
408
345
  'org_01EGS4P7QR31EZ4YWD1Z1XA176',
409
346
  )
410
347
  end
@@ -412,48 +349,73 @@ describe WorkOS::SSO do
412
349
  end
413
350
 
414
351
  context 'with limit option' do
415
- it 'returns connections' do
416
- VCR.use_cassette('sso/list_connections_with_limit_param') do
417
- connections = WorkOS::SSO.list_connections(
418
- limit: 1,
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,
419
366
  )
420
- expect(connections.size).to eq(1)
367
+
368
+ expect(connections.data.size).to eq(2)
421
369
  end
422
370
  end
423
371
  end
424
372
 
425
373
  context 'with before option' do
426
- it 'returns connections' do
427
- VCR.use_cassette('sso/list_connections_with_before_param') do
428
- connections = WorkOS::SSO.list_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(
429
387
  before: 'conn_01EQKPMQAPV02H270HKVNS4CTA',
430
388
  )
431
- expect(connections.size).to eq(1)
389
+
390
+ expect(connections.data.size).to eq(3)
432
391
  end
433
392
  end
434
393
  end
435
394
 
436
395
  context 'with after option' do
437
- it 'returns connections' do
438
- VCR.use_cassette('sso/list_connections_with_after_param') do
439
- connections = WorkOS::SSO.list_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(
440
409
  after: 'conn_01EQKPMQAPV02H270HKVNS4CTA',
441
410
  )
442
- expect(connections.size).to eq(1)
411
+
412
+ expect(connections.data.size).to eq(3)
443
413
  end
444
414
  end
445
415
  end
446
416
  end
447
417
 
448
418
  describe '.get_connection' do
449
- before(:all) do
450
- WorkOS.key = 'key'
451
- end
452
-
453
- after(:all) do
454
- WorkOS.key = nil
455
- end
456
-
457
419
  context 'with a valid id' do
458
420
  it 'gets the connection details' do
459
421
  VCR.use_cassette('sso/get_connection_with_valid_id') do
@@ -484,14 +446,6 @@ describe WorkOS::SSO do
484
446
  end
485
447
 
486
448
  describe '.delete_connection' do
487
- before(:all) do
488
- WorkOS.key = 'key'
489
- end
490
-
491
- after(:all) do
492
- WorkOS.key = nil
493
- end
494
-
495
449
  context 'with a valid id' do
496
450
  it 'returns true' do
497
451
  VCR.use_cassette('sso/delete_connection_with_valid_id') do