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.
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