openstax_salesforce 0.9.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +91 -0
- data/Rakefile +30 -0
- data/app/controllers/openstax/salesforce/application_controller.rb +5 -0
- data/app/controllers/openstax/salesforce/settings_controller.rb +20 -0
- data/app/helpers/openstax/salesforce/application_helper.rb +11 -0
- data/app/models/openstax/salesforce/user.rb +25 -0
- data/app/models/user.rb +25 -0
- data/app/views/openstax/salesforce/settings/show.html.erb +33 -0
- data/config/initializers/omniauth.rb +8 -0
- data/config/initializers/openstax_salesforce.rb +48 -0
- data/config/routes.rb +11 -0
- data/db/migrate/0_install_openstax_salesforce.rb +12 -0
- data/lib/openstax/salesforce/active_force.rb +34 -0
- data/lib/openstax/salesforce/client.rb +24 -0
- data/lib/openstax/salesforce/engine.rb +9 -0
- data/lib/openstax/salesforce/remote/book.rb +7 -0
- data/lib/openstax/salesforce/remote/contact.rb +18 -0
- data/lib/openstax/salesforce/remote/lead.rb +22 -0
- data/lib/openstax/salesforce/remote/school.rb +7 -0
- data/lib/openstax/salesforce/spec_helpers/salesforce_proxy.rb +99 -0
- data/lib/openstax/salesforce/spec_helpers.rb +58 -0
- data/lib/openstax/salesforce/user_missing.rb +3 -0
- data/lib/openstax/salesforce/version.rb +5 -0
- data/lib/openstax_salesforce.rb +58 -0
- data/lib/tasks/openstax_salesforce_tasks.rake +47 -0
- data/spec/client_spec.rb +10 -0
- data/spec/dummy/README.md +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/schema.rb +26 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +50 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/openstax/salesforce/spec_helpers_spec.rb +31 -0
- data/spec/rails_helper.rb +55 -0
- data/spec/spec_helper.rb +86 -0
- metadata +292 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 66066f14c2a63bbba0e2e92314c1841447a8bb58
|
|
4
|
+
data.tar.gz: 0188ff2c949728a8c47f4305b14ea57bc4324f71
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 31776fad63147b4f3d8931930679c5665c2141cd61b78e5b21a0d91403fdcb7df3207e8237c49594501fc6cb6b96cb1acbb60519f21e384f1fd888376c92d6b7
|
|
7
|
+
data.tar.gz: ef1ffb3e25b322aabf3fa2d3972baa9e5589f09c9f2721e888eb935bc3fca601c89d15c23b4b88f43a88338b52138d29aaacbcae23539b86ba77327b27523437
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2017 JP Slavinsky
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# OpenStax::Salesforce
|
|
2
|
+
|
|
3
|
+
[](http://badge.fury.io/rb/fine_print)
|
|
4
|
+
[](https://travis-ci.org/openstax/openstax_salesforce)
|
|
5
|
+
[](https://codeclimate.com/github/openstax/openstax_salesforce)
|
|
6
|
+
|
|
7
|
+
OpenStax::Salesforce is a Rails engine used by OpenStax projects to communicate with the OpenStax Salesforce instance.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add these line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```rb
|
|
14
|
+
gem 'openstax_salesforce'
|
|
15
|
+
|
|
16
|
+
# ActiveForce fork that supports Ruby >= 2.1 and stubbable stdout
|
|
17
|
+
gem 'active_force', git: 'https://github.com/openstax/active_force', ref: '7caac17'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
And then execute:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
$ bundle
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or install it yourself:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
$ gem install openstax_salesforce
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then execute the following command to copy the necessary migration and the initializer to your application:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
$ rake openstax_salesforce:install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
And then migrate your database:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
$ rake db:migrate
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Also add OpenStax::Salesforce to your application's routes:
|
|
45
|
+
|
|
46
|
+
```rb
|
|
47
|
+
mount OpenStax::Salesforce::Engine, at: "/salesforce"
|
|
48
|
+
OpenStax::Salesforce.set_top_level_routes(self)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The `set_top_level_routes` should be called at the top level inside `routes.rb`. It adds oauth callback
|
|
52
|
+
routes at the top level.
|
|
53
|
+
|
|
54
|
+
And provide a link on your site for administrators to access the engine.
|
|
55
|
+
|
|
56
|
+
```erb
|
|
57
|
+
<%= link_to 'Salesforce Setup', openstax_salesforce_path %>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
After installation, the initializer for OpenStax::Salesforce will be located under
|
|
63
|
+
`config/initializers/openstax_salesforce.rb`. Make sure to configure it to suit
|
|
64
|
+
your needs. Pay particular attention to `authenticate_admin_proc`,
|
|
65
|
+
as you will be unable to access the setup pages until this proc is setup to return
|
|
66
|
+
`true` for your admins.
|
|
67
|
+
|
|
68
|
+
## Testing
|
|
69
|
+
|
|
70
|
+
From the gem's main folder, run `bundle install`,
|
|
71
|
+
`bundle exec rake db:migrate` and then
|
|
72
|
+
`bundle exec rake` to run all the specs.
|
|
73
|
+
|
|
74
|
+
## Specs in Parent App
|
|
75
|
+
|
|
76
|
+
There's a helper you can include in your parent app's salesforce specs. It isn't automatically
|
|
77
|
+
required by this engine, so you have to do it manually in your spec:
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
require 'openstax/salesforce/spec_helper'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Contributing
|
|
84
|
+
|
|
85
|
+
1. Fork it
|
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
87
|
+
3. Create specs for your feature
|
|
88
|
+
4. Ensure that all specs pass
|
|
89
|
+
5. Commit your changes (`git commit -am 'Add some feature'`)
|
|
90
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
|
91
|
+
7. Create new pull request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rdoc/task'
|
|
8
|
+
|
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
11
|
+
rdoc.title = 'OpenStax::Salesforce'
|
|
12
|
+
rdoc.options << '--line-numbers'
|
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
|
18
|
+
load 'rails/tasks/engine.rake'
|
|
19
|
+
|
|
20
|
+
load 'rails/tasks/statistics.rake'
|
|
21
|
+
|
|
22
|
+
Bundler::GemHelper.install_tasks
|
|
23
|
+
|
|
24
|
+
require 'rspec/core'
|
|
25
|
+
require 'rspec/core/rake_task'
|
|
26
|
+
|
|
27
|
+
desc 'Run all specs in spec directory (excluding plugin specs)'
|
|
28
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
|
29
|
+
|
|
30
|
+
task :default => :spec
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module OpenStax::Salesforce
|
|
2
|
+
class SettingsController < OpenStax::Salesforce::ApplicationController
|
|
3
|
+
layout OpenStax::Salesforce.configuration.layout
|
|
4
|
+
|
|
5
|
+
def show
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def callback
|
|
9
|
+
OpenStax::Salesforce::User.save_from_omniauth!(env["omniauth.auth"])
|
|
10
|
+
redirect_to root_path
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def destroy_user
|
|
14
|
+
OpenStax::Salesforce::User.destroy_all
|
|
15
|
+
ActiveForce.clear_sfdc_client! # since user is now gone, any client invalid
|
|
16
|
+
redirect_to root_path
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module OpenStax::Salesforce
|
|
2
|
+
class User < ActiveRecord::Base
|
|
3
|
+
validates :uid, presence: true
|
|
4
|
+
validates :oauth_token, presence: true
|
|
5
|
+
validates :refresh_token, presence: true
|
|
6
|
+
validates :instance_url, presence: true
|
|
7
|
+
|
|
8
|
+
after_save :ensure_only_one_record
|
|
9
|
+
|
|
10
|
+
def self.save_from_omniauth!(auth)
|
|
11
|
+
where(auth.slice(:uid).permit!).first_or_initialize.tap do |user|
|
|
12
|
+
user.uid = auth.uid
|
|
13
|
+
user.name = auth.info.name
|
|
14
|
+
user.oauth_token = auth.credentials.token
|
|
15
|
+
user.refresh_token = auth.credentials.refresh_token
|
|
16
|
+
user.instance_url = auth.credentials.instance_url
|
|
17
|
+
user.save!
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ensure_only_one_record
|
|
22
|
+
self.class.where{id != self.id}.destroy_all
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/app/models/user.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module OpenStax::Salesforce
|
|
2
|
+
class User < ActiveRecord::Base
|
|
3
|
+
validates :uid, presence: true
|
|
4
|
+
validates :oauth_token, presence: true
|
|
5
|
+
validates :refresh_token, presence: true
|
|
6
|
+
validates :instance_url, presence: true
|
|
7
|
+
|
|
8
|
+
after_save :ensure_only_one_record
|
|
9
|
+
|
|
10
|
+
def self.save_from_omniauth!(auth)
|
|
11
|
+
where(auth.slice(:uid).permit!).first_or_initialize.tap do |user|
|
|
12
|
+
user.uid = auth.uid
|
|
13
|
+
user.name = auth.info.name
|
|
14
|
+
user.oauth_token = auth.credentials.token
|
|
15
|
+
user.refresh_token = auth.credentials.refresh_token
|
|
16
|
+
user.instance_url = auth.credentials.instance_url
|
|
17
|
+
user.save!
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ensure_only_one_record
|
|
22
|
+
self.class.where{id != self.id}.destroy_all
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<div class="salesforce-settings">
|
|
2
|
+
|
|
3
|
+
<%= page_heading(self, "Salesforce Setup") %>
|
|
4
|
+
|
|
5
|
+
<p>When Accounts makes calls to Salesforce's API, it must do so on behalf of a
|
|
6
|
+
specific Salesforce user. At any one time, Accounts has information for either
|
|
7
|
+
zero or one such user. Use the link below to set the current user that Accounts
|
|
8
|
+
acts as when calling the Salesforce API.</p>
|
|
9
|
+
|
|
10
|
+
<% @user = OpenStax::Salesforce::User.first %>
|
|
11
|
+
|
|
12
|
+
<div style="margin: 30px 0px">
|
|
13
|
+
<p>
|
|
14
|
+
<% if @user.present? %>
|
|
15
|
+
The current Salesforce user is <b><%= @user.name || "[Unknown Name]" %></b>.
|
|
16
|
+
<% else %>
|
|
17
|
+
There <b>is no</b> Salesforce user currently set.
|
|
18
|
+
<% end %>
|
|
19
|
+
</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<%= link_to "Set Salesforce User",
|
|
23
|
+
"/auth/salesforce?redirect_uri=#{main_app.auth_salesforce_callback_url}",
|
|
24
|
+
id: "sign_in", class: 'btn btn-primary' %>
|
|
25
|
+
|
|
26
|
+
<%= link_to "Clear Salesforce User",
|
|
27
|
+
destroy_user_settings_path,
|
|
28
|
+
class: 'btn btn-danger pull-right',
|
|
29
|
+
method: :delete %>
|
|
30
|
+
|
|
31
|
+
<hr/>
|
|
32
|
+
|
|
33
|
+
</div>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
|
2
|
+
unless OpenStax::Salesforce.configuration.skip_automatic_omniauth_setup
|
|
3
|
+
provider :salesforce,
|
|
4
|
+
OpenStax::Salesforce.configuration.salesforce_client_key,
|
|
5
|
+
OpenStax::Salesforce.configuration.salesforce_client_secret,
|
|
6
|
+
client_options: OpenStax::Salesforce.configuration.salesforce_client_options
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# This initializer always runs before the engine is loaded, but it can
|
|
2
|
+
# also be copied to the application's initializers by running the install
|
|
3
|
+
# task. Because this code can get run multiple times, make sure to only put
|
|
4
|
+
# code here that is amenable to that.
|
|
5
|
+
|
|
6
|
+
OpenStax::Salesforce.configure do |config|
|
|
7
|
+
# Layout to be used for OpenStax::Salesforce's controllers
|
|
8
|
+
config.layout = 'application'
|
|
9
|
+
|
|
10
|
+
# Proc called with a controller as self. Returns the current user.
|
|
11
|
+
config.current_user_proc = -> { nil }
|
|
12
|
+
|
|
13
|
+
# Proc called with a user as argument and a controller as self.
|
|
14
|
+
# This proc is called when a user tries to access the engine's controllers.
|
|
15
|
+
# Should raise an exception, render or redirect unless the user is a manager
|
|
16
|
+
# or admin. The default renders 403 Forbidden for all users.
|
|
17
|
+
# Note: Proc must account for nil users, if current_user_proc returns nil.
|
|
18
|
+
config.authenticate_admin_proc = ->(user) { head(:forbidden) }
|
|
19
|
+
|
|
20
|
+
# Consumer key and secret for connecting to the Salesforce app
|
|
21
|
+
config.salesforce_client_key = 'put_real_key_value_here'
|
|
22
|
+
config.salesforce_client_secret = 'put_real_secret_value_here'
|
|
23
|
+
|
|
24
|
+
# Uncomment this to override the login site for sandbox instances; ok to be nil
|
|
25
|
+
# config.salesforce_login_site = 'https://test.salesforce.com'
|
|
26
|
+
|
|
27
|
+
# The following sandbox tokens are used for specs to connect to a sandbox Salesforce
|
|
28
|
+
# instance.
|
|
29
|
+
if Rails.env.test?
|
|
30
|
+
config.sandbox_oauth_token = 'put_real_value_here'
|
|
31
|
+
config.sandbox_refresh_token = 'put_real_value_here'
|
|
32
|
+
config.sandbox_instance_url = 'put_real_value_here'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Change this to true if you want to call the omniauth setup on your own
|
|
36
|
+
config.skip_automatic_omniauth_setup = false
|
|
37
|
+
|
|
38
|
+
# If `check_sandbox_instance_url` is true (default), the spec helper that
|
|
39
|
+
# uses the instance URL will checks that the URL starts with "cs", which
|
|
40
|
+
# indicates that the instance is a sandbox.
|
|
41
|
+
config.check_sandbox_instance_url = true
|
|
42
|
+
|
|
43
|
+
# A way to customize page headings. Sometimes apps fold the page heading
|
|
44
|
+
# into the layout in different ways.
|
|
45
|
+
config.page_heading_proc = ->(view, text) { "<h2>#{text}</h2>".html_safe }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class InstallOpenStaxSalesforce < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :openstax_salesforce_users do |t|
|
|
4
|
+
t.string :name
|
|
5
|
+
t.string :uid, null: false
|
|
6
|
+
t.string :oauth_token, null: false
|
|
7
|
+
t.string :refresh_token, null: false
|
|
8
|
+
t.string :instance_url, null: false
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Monkey patching
|
|
2
|
+
|
|
3
|
+
module ActiveForce
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
|
|
7
|
+
# Use a lazy setting of the client so that migrations etc are in place
|
|
8
|
+
# to allow the Client to be successfully instantiated.
|
|
9
|
+
alias_method :original_sfdc_client, :sfdc_client
|
|
10
|
+
def sfdc_client
|
|
11
|
+
if !original_sfdc_client.is_a?(OpenStax::Salesforce::Client)
|
|
12
|
+
self.sfdc_client = OpenStax::Salesforce::Client.new
|
|
13
|
+
end
|
|
14
|
+
original_sfdc_client
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def clear_sfdc_client!
|
|
18
|
+
self.sfdc_client = nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class SObject
|
|
24
|
+
# Save that precious SF API call count!
|
|
25
|
+
def save_if_changed
|
|
26
|
+
save if changed?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# We sometimes mock `query` in specs, and it is helpful to have
|
|
30
|
+
# access to the original implementation
|
|
31
|
+
singleton_class.send(:alias_method, :original_query, :query)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module OpenStax::Salesforce
|
|
2
|
+
class Client < ::Restforce::Data::Client
|
|
3
|
+
|
|
4
|
+
def initialize
|
|
5
|
+
user = User.first
|
|
6
|
+
|
|
7
|
+
raise(UserMissing, "The Salesforce client was requested but no user is available.") if user.nil?
|
|
8
|
+
|
|
9
|
+
client_key = OpenStax::Salesforce.configuration.salesforce_client_key
|
|
10
|
+
client_secret = OpenStax::Salesforce.configuration.salesforce_client_secret
|
|
11
|
+
|
|
12
|
+
raise(IllegalState, "The Salesforce key is missing") if client_key.nil?
|
|
13
|
+
raise(IllegalState, "The Salesforce secret is missing") if client_secret.nil?
|
|
14
|
+
|
|
15
|
+
super(oauth_token: user.oauth_token,
|
|
16
|
+
refresh_token: user.refresh_token,
|
|
17
|
+
instance_url: user.instance_url,
|
|
18
|
+
client_id: client_key,
|
|
19
|
+
client_secret: client_secret,
|
|
20
|
+
api_version: '37.0')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module OpenStax::Salesforce::Remote
|
|
2
|
+
class Contact < ActiveForce::SObject
|
|
3
|
+
belongs_to :school, foreign_key: :school_id,
|
|
4
|
+
model: OpenStax::Salesforce::Remote::School
|
|
5
|
+
|
|
6
|
+
field :name, from: "Name"
|
|
7
|
+
field :first_name, from: "FirstName"
|
|
8
|
+
field :last_name, from: "LastName"
|
|
9
|
+
field :email, from: "Email"
|
|
10
|
+
field :email_alt, from: "Email_alt__c"
|
|
11
|
+
field :faculty_confirmed_date, from: "Faculty_Confirmed_Date__c", as: :datetime
|
|
12
|
+
field :faculty_verified, from: "Faculty_Verified__c"
|
|
13
|
+
field :last_modified_at, from: "LastModifiedDate"
|
|
14
|
+
field :school_id, from: "AccountId"
|
|
15
|
+
|
|
16
|
+
self.table_name = 'Contact'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module OpenStax::Salesforce::Remote
|
|
2
|
+
class Lead < ActiveForce::SObject
|
|
3
|
+
field :name, from: "Name"
|
|
4
|
+
field :first_name, from: "FirstName"
|
|
5
|
+
field :last_name, from: "LastName"
|
|
6
|
+
field :salutation, from: "Salutation"
|
|
7
|
+
field :subject, from: "Subject__c"
|
|
8
|
+
field :school, from: "Company"
|
|
9
|
+
field :phone, from: "Phone"
|
|
10
|
+
field :website, from: "Website"
|
|
11
|
+
field :status, from: "Status"
|
|
12
|
+
field :email, from: "Email"
|
|
13
|
+
field :source, from: "LeadSource"
|
|
14
|
+
field :newsletter, from: "Newsletter__c"
|
|
15
|
+
field :newsletter_opt_in, from: "Newsletter_Opt_In__c"
|
|
16
|
+
field :adoption_status, from: "Adoption_Status__c"
|
|
17
|
+
field :num_students, from: "Number_of_Students__c"
|
|
18
|
+
field :os_accounts_id, from: "OS_Accounts_ID__c"
|
|
19
|
+
|
|
20
|
+
self.table_name = 'Lead'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module OpenStax::Salesforce::SpecHelpers
|
|
2
|
+
class SalesforceProxy
|
|
3
|
+
|
|
4
|
+
include OpenStax::Salesforce::Remote
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Used to filter records to the scope of one spec
|
|
10
|
+
def reset_unique_token(token = SecureRandom.hex(10))
|
|
11
|
+
@unique_token = token
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def clear_unique_token
|
|
15
|
+
@unique_token = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def new_contact(first_name: nil, last_name: nil, school_name: "JP University",
|
|
19
|
+
email: nil, email_alt: nil,
|
|
20
|
+
faculty_verified: nil)
|
|
21
|
+
ensure_schools_exist([school_name])
|
|
22
|
+
|
|
23
|
+
Contact.new(
|
|
24
|
+
first_name: first_name || Faker::Name.first_name,
|
|
25
|
+
last_name: last_name!(last_name),
|
|
26
|
+
school_id: school_id(school_name),
|
|
27
|
+
email: email,
|
|
28
|
+
email_alt: email_alt,
|
|
29
|
+
faculty_verified: faculty_verified
|
|
30
|
+
).tap do |contact|
|
|
31
|
+
if !contact.save
|
|
32
|
+
raise "Could not save SF contact: #{contact.errors}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def new_lead(email:, status: nil, last_name: nil, school_name: "JP University")
|
|
38
|
+
Lead.new(
|
|
39
|
+
email: email,
|
|
40
|
+
status: status,
|
|
41
|
+
last_name: last_name!(last_name),
|
|
42
|
+
school: school_name
|
|
43
|
+
).tap do |lead|
|
|
44
|
+
if !lead.save
|
|
45
|
+
raise "Could not save SF lead: #{lead.errors}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def last_name!(input)
|
|
51
|
+
"#{input || Faker::Name.last_name}#{@unique_token if @unique_token.present?}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def ensure_books_exist(book_names)
|
|
55
|
+
book_names.each do |book_name|
|
|
56
|
+
if books.none?{|bb| bb.name == book_name}
|
|
57
|
+
book = Book.new(name: book_name)
|
|
58
|
+
book.save!
|
|
59
|
+
books.push(book)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def ensure_schools_exist(school_names)
|
|
65
|
+
school_names.compact.each do |school_name|
|
|
66
|
+
if schools.none?{|ss| ss.name == school_name}
|
|
67
|
+
school = School.new(name: school_name)
|
|
68
|
+
school.save!
|
|
69
|
+
schools.push(school)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def books
|
|
75
|
+
@books ||= Book.all
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def book(name)
|
|
79
|
+
books.select{|bb| bb.name == name}.first
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def book_id(name)
|
|
83
|
+
book(name).id
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def schools
|
|
87
|
+
@schools ||= School.all
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def school_id(name)
|
|
91
|
+
school(name).try(:id)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def school(name)
|
|
95
|
+
schools.select{|ss| ss.name == name}.first
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'openstax/salesforce/spec_helpers/salesforce_proxy'
|
|
2
|
+
|
|
3
|
+
module OpenStax::Salesforce::SpecHelpers
|
|
4
|
+
|
|
5
|
+
def load_salesforce_user
|
|
6
|
+
clear_salesforce_user
|
|
7
|
+
|
|
8
|
+
config = OpenStax::Salesforce.configuration
|
|
9
|
+
sf_user = OpenStax::Salesforce::User.new
|
|
10
|
+
|
|
11
|
+
sf_user.name = "some name"
|
|
12
|
+
sf_user.uid = "whatever"
|
|
13
|
+
sf_user.oauth_token = config.sandbox_oauth_token
|
|
14
|
+
sf_user.refresh_token = config.sandbox_refresh_token
|
|
15
|
+
sf_user.instance_url = config.sandbox_instance_url.tap do |url|
|
|
16
|
+
if config.check_sandbox_instance_url && !url.match(/\/\/cs/)
|
|
17
|
+
raise "Salesforce sandbox instance URL (#{url}) does not have the expected form!"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
sf_user.save!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def clear_salesforce_user
|
|
25
|
+
OpenStax::Salesforce::User.destroy_all
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def limit_salesforce_queries(remote_class, **conditions)
|
|
29
|
+
allow(remote_class).to receive(:query) do
|
|
30
|
+
like_conditions = {}
|
|
31
|
+
other_conditions = {}
|
|
32
|
+
|
|
33
|
+
conditions.each_pair do |key, value|
|
|
34
|
+
if value.is_a?(String) && value.include?("%")
|
|
35
|
+
like_conditions[key] = value
|
|
36
|
+
else
|
|
37
|
+
other_conditions[key] = value
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
like_queries = like_conditions.map do |key, value|
|
|
42
|
+
attribute = remote_class.mapping.mappings[key]
|
|
43
|
+
quoted_value = "'#{value.gsub(/\\/, '\&\&').gsub(/'/, "''")}'"
|
|
44
|
+
"#{attribute} LIKE #{quoted_value}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
result = remote_class.original_query
|
|
48
|
+
|
|
49
|
+
like_queries.each do |like_query|
|
|
50
|
+
result = result.where(like_query)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
result = result.where(other_conditions) if other_conditions.any?
|
|
54
|
+
result
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|