openstax_salesforce 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +91 -0
  4. data/Rakefile +30 -0
  5. data/app/controllers/openstax/salesforce/application_controller.rb +5 -0
  6. data/app/controllers/openstax/salesforce/settings_controller.rb +20 -0
  7. data/app/helpers/openstax/salesforce/application_helper.rb +11 -0
  8. data/app/models/openstax/salesforce/user.rb +25 -0
  9. data/app/models/user.rb +25 -0
  10. data/app/views/openstax/salesforce/settings/show.html.erb +33 -0
  11. data/config/initializers/omniauth.rb +8 -0
  12. data/config/initializers/openstax_salesforce.rb +48 -0
  13. data/config/routes.rb +11 -0
  14. data/db/migrate/0_install_openstax_salesforce.rb +12 -0
  15. data/lib/openstax/salesforce/active_force.rb +34 -0
  16. data/lib/openstax/salesforce/client.rb +24 -0
  17. data/lib/openstax/salesforce/engine.rb +9 -0
  18. data/lib/openstax/salesforce/remote/book.rb +7 -0
  19. data/lib/openstax/salesforce/remote/contact.rb +18 -0
  20. data/lib/openstax/salesforce/remote/lead.rb +22 -0
  21. data/lib/openstax/salesforce/remote/school.rb +7 -0
  22. data/lib/openstax/salesforce/spec_helpers/salesforce_proxy.rb +99 -0
  23. data/lib/openstax/salesforce/spec_helpers.rb +58 -0
  24. data/lib/openstax/salesforce/user_missing.rb +3 -0
  25. data/lib/openstax/salesforce/version.rb +5 -0
  26. data/lib/openstax_salesforce.rb +58 -0
  27. data/lib/tasks/openstax_salesforce_tasks.rake +47 -0
  28. data/spec/client_spec.rb +10 -0
  29. data/spec/dummy/README.md +28 -0
  30. data/spec/dummy/Rakefile +6 -0
  31. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  32. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  33. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  34. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  35. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  36. data/spec/dummy/bin/bundle +3 -0
  37. data/spec/dummy/bin/rails +4 -0
  38. data/spec/dummy/bin/rake +4 -0
  39. data/spec/dummy/bin/setup +29 -0
  40. data/spec/dummy/config/application.rb +26 -0
  41. data/spec/dummy/config/boot.rb +5 -0
  42. data/spec/dummy/config/database.yml +25 -0
  43. data/spec/dummy/config/environment.rb +5 -0
  44. data/spec/dummy/config/environments/development.rb +41 -0
  45. data/spec/dummy/config/environments/production.rb +79 -0
  46. data/spec/dummy/config/environments/test.rb +42 -0
  47. data/spec/dummy/config/initializers/assets.rb +11 -0
  48. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  50. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  51. data/spec/dummy/config/initializers/inflections.rb +16 -0
  52. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  53. data/spec/dummy/config/initializers/session_store.rb +3 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/en.yml +23 -0
  56. data/spec/dummy/config/routes.rb +3 -0
  57. data/spec/dummy/config/secrets.yml +22 -0
  58. data/spec/dummy/config.ru +4 -0
  59. data/spec/dummy/db/schema.rb +26 -0
  60. data/spec/dummy/db/test.sqlite3 +0 -0
  61. data/spec/dummy/log/test.log +50 -0
  62. data/spec/dummy/public/404.html +67 -0
  63. data/spec/dummy/public/422.html +67 -0
  64. data/spec/dummy/public/500.html +66 -0
  65. data/spec/dummy/public/favicon.ico +0 -0
  66. data/spec/openstax/salesforce/spec_helpers_spec.rb +31 -0
  67. data/spec/rails_helper.rb +55 -0
  68. data/spec/spec_helper.rb +86 -0
  69. 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
+ [![Gem Version](https://badge.fury.io/rb/openstax_salesforce.svg)](http://badge.fury.io/rb/fine_print)
4
+ [![Build Status](https://travis-ci.org/openstax/openstax_salesforce.svg?branch=master)](https://travis-ci.org/openstax/openstax_salesforce)
5
+ [![Code Climate](https://codeclimate.com/github/openstax/openstax_salesforce/badges/gpa.svg)](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,5 @@
1
+ module OpenStax::Salesforce
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -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,11 @@
1
+ module OpenStax::Salesforce
2
+ module ApplicationHelper
3
+ def config
4
+ OpenStax::Salesforce.configuration
5
+ end
6
+
7
+ def page_heading(context, text)
8
+ config.page_heading_proc.call(context, text)
9
+ end
10
+ end
11
+ 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
@@ -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,11 @@
1
+ OpenStax::Salesforce::Engine.routes.draw do
2
+ root to: 'settings#show'
3
+
4
+ resource :settings, only: [:show] do
5
+ collection do
6
+ delete :destroy_user
7
+ end
8
+ end
9
+
10
+
11
+ end
@@ -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,9 @@
1
+ ActiveSupport::Inflector.inflections do |inflect|
2
+ inflect.acronym 'OpenStax'
3
+ end
4
+
5
+ module OpenStax::Salesforce
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace OpenStax::Salesforce
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module OpenStax::Salesforce::Remote
2
+ class Book < ActiveForce::SObject
3
+ field :name, from: "Name"
4
+
5
+ self.table_name = 'Book__c'
6
+ end
7
+ 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,7 @@
1
+ module OpenStax::Salesforce::Remote
2
+ class School < ActiveForce::SObject
3
+ field :name, from: "Name"
4
+
5
+ self.table_name = 'Account'
6
+ end
7
+ 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
@@ -0,0 +1,3 @@
1
+ module OpenStax::Salesforce
2
+ class UserMissing < StandardError; end
3
+ end
@@ -0,0 +1,5 @@
1
+ module OpenStax
2
+ module Salesforce
3
+ VERSION = "0.9.0"
4
+ end
5
+ end