mno-enterprise-core 3.0.7 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/images/mno_enterprise/login-background.jpg +0 -0
- data/app/assets/stylesheets/mno_enterprise/mail.css +27 -0
- data/app/helpers/mno_enterprise/application_helper.rb +14 -0
- data/app/helpers/mno_enterprise/impersonate_helper.rb +1 -1
- data/app/models/mno_enterprise/app.rb +2 -1
- data/app/models/mno_enterprise/base_resource.rb +1 -2
- data/app/models/mno_enterprise/impac/dashboard.rb +3 -1
- data/app/models/mno_enterprise/impac/kpi.rb +1 -1
- data/app/models/mno_enterprise/impac/widget.rb +1 -1
- data/app/models/mno_enterprise/org_invite.rb +2 -1
- data/app/models/mno_enterprise/tenant.rb +2 -4
- data/app/models/mno_enterprise/user.rb +6 -0
- data/app/pdf/mno_enterprise/invoice_pdf.rb +29 -12
- data/app/views/system_notifications/confirmation-instructions.html.erb +26 -0
- data/app/views/system_notifications/confirmation-instructions.text.erb +10 -0
- data/app/views/system_notifications/delete-request-instructions.html.erb +31 -0
- data/app/views/system_notifications/delete-request-instructions.text.erb +15 -0
- data/app/views/system_notifications/organization-invite-existing-user.html.erb +30 -0
- data/app/views/system_notifications/organization-invite-existing-user.text.erb +13 -0
- data/app/views/system_notifications/organization-invite-new-user.html.erb +30 -0
- data/app/views/system_notifications/organization-invite-new-user.text.erb +14 -0
- data/app/views/system_notifications/reconfirmation-instructions.html.erb +27 -0
- data/app/views/system_notifications/reconfirmation-instructions.text.erb +10 -0
- data/app/views/system_notifications/registration-instructions.html.erb +27 -0
- data/app/views/system_notifications/registration-instructions.text.erb +9 -0
- data/app/views/system_notifications/reset-password-instructions.html.erb +27 -0
- data/app/views/system_notifications/reset-password-instructions.text.erb +11 -0
- data/app/views/system_notifications/unlock-instructions.html.erb +27 -0
- data/app/views/system_notifications/unlock-instructions.text.erb +10 -0
- data/config/initializers/audit_log.rb +2 -0
- data/config/locales/templates/dashboard/organization/en.yml +2 -0
- data/config/locales/views/auth/registrations/en.yml +1 -1
- data/lib/devise/hooks/impersonatable.rb +14 -0
- data/lib/devise_extension.rb +9 -2
- data/lib/generators/mno_enterprise/install/templates/config/application.yml +6 -2
- data/lib/generators/mno_enterprise/install/templates/config/initializers/mno_enterprise.rb +6 -1
- data/lib/generators/mno_enterprise/install/templates/config/settings.yml +2 -0
- data/lib/generators/mno_enterprise/install/templates/config/settings/uat.yml +2 -2
- data/lib/generators/mno_enterprise/install/templates/stylesheets/main.less +4 -0
- data/lib/her_extension/model/relation.rb +0 -13
- data/lib/mandrill_client.rb +13 -41
- data/lib/mno_enterprise/concerns/models/ability.rb +12 -0
- data/lib/mno_enterprise/concerns/models/organization.rb +5 -2
- data/lib/mno_enterprise/core.rb +21 -8
- data/lib/mno_enterprise/mail_adapters/adapter.rb +51 -0
- data/lib/mno_enterprise/mail_adapters/mandrill_adapter.rb +39 -0
- data/lib/mno_enterprise/mail_adapters/smtp_adapter.rb +21 -0
- data/lib/mno_enterprise/mail_adapters/sparkpost_adapter.rb +56 -0
- data/lib/mno_enterprise/mail_adapters/test_adapter.rb +21 -0
- data/lib/mno_enterprise/mail_client.rb +28 -0
- data/lib/mno_enterprise/smtp_client.rb +32 -0
- data/lib/mno_enterprise/testing_support/factories/apps.rb +1 -2
- data/lib/mno_enterprise/testing_support/factories/impac/kpis.rb +1 -0
- data/lib/mno_enterprise/testing_support/factories/tenant.rb +1 -7
- data/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb +1 -2
- data/lib/mno_enterprise/version.rb +1 -1
- data/spec/lib/her_extension/model/relation_spec.rb +0 -71
- data/spec/lib/mandrill_client_spec.rb +27 -42
- data/spec/lib/mno_enterprise/mail_adapters/adapter_spec.rb +29 -0
- data/spec/lib/mno_enterprise/mail_adapters/mandrill_adapter_spec.rb +53 -0
- data/spec/lib/mno_enterprise/mail_adapters/smtp_adapter_spec.rb +29 -0
- data/spec/lib/mno_enterprise/mail_adapters/sparkpost_adapter_spec.rb +60 -0
- data/spec/lib/mno_enterprise/mail_client_spec.rb +9 -0
- data/spec/lib/mno_enterprise/smtp_client_spec.rb +39 -0
- data/spec/models/mno_enterprise/ability_spec.rb +21 -0
- data/spec/models/mno_enterprise/base_resource_spec.rb +0 -22
- metadata +76 -24
- data/lib/her_extension/middleware/mnoe_raise_error.rb +0 -21
- data/lib/her_extension/model/associations/belongs_to_association.rb +0 -25
data/lib/mno_enterprise/core.rb
CHANGED
@@ -17,9 +17,7 @@ require "her_extension/model/parse"
|
|
17
17
|
require "her_extension/model/associations/association"
|
18
18
|
require "her_extension/model/associations/association_proxy"
|
19
19
|
require "her_extension/model/associations/has_many_association"
|
20
|
-
require "her_extension/model/associations/belongs_to_association"
|
21
20
|
require "her_extension/middleware/mnoe_api_v1_parse_json"
|
22
|
-
require "her_extension/middleware/mnoe_raise_error"
|
23
21
|
require "faraday_middleware"
|
24
22
|
require "mno_enterprise/engine"
|
25
23
|
|
@@ -29,7 +27,6 @@ require 'mno_enterprise/database_extendable'
|
|
29
27
|
require 'config'
|
30
28
|
require 'figaro'
|
31
29
|
|
32
|
-
require 'mandrill'
|
33
30
|
require "mandrill_client"
|
34
31
|
|
35
32
|
require 'accountingjs_serializer'
|
@@ -161,11 +158,26 @@ module MnoEnterprise
|
|
161
158
|
#====================================
|
162
159
|
# Emailing
|
163
160
|
#====================================
|
161
|
+
# @deprecated: Use ENV['MANDRILL_API_KEY']
|
164
162
|
# Mandrill Key for sending emails
|
165
|
-
|
166
|
-
|
163
|
+
def self.mandrill_key
|
164
|
+
warn "[DEPRECATION] `mandrill_key` is deprecated. Use `ENV['MANDRILL_API_KEY']`."
|
165
|
+
@@mandrill_key
|
166
|
+
end
|
167
|
+
def self.mandrill_key=(mandrill_key)
|
168
|
+
warn "[DEPRECATION] `mandrill_key` is deprecated. Use `ENV['MANDRILL_API_KEY']`."
|
169
|
+
@@mandrill_key = mandrill_key
|
170
|
+
end
|
167
171
|
@@mandrill_key = nil
|
168
172
|
|
173
|
+
# Adapter used to send emails
|
174
|
+
# Default to :mandrill
|
175
|
+
mattr_reader(:mail_adapter) { Rails.env.test? ? :test : :mandrill }
|
176
|
+
def self.mail_adapter=(adapter)
|
177
|
+
@@mail_adapter = adapter
|
178
|
+
MnoEnterprise::MailClient.adapter = self.mail_adapter
|
179
|
+
end
|
180
|
+
|
169
181
|
# The support email address
|
170
182
|
mattr_accessor :support_email
|
171
183
|
@@support_email = "support@example.com"
|
@@ -236,6 +248,10 @@ module MnoEnterprise
|
|
236
248
|
yield self
|
237
249
|
self.configure_styleguide
|
238
250
|
self.configure_api
|
251
|
+
|
252
|
+
# Mail config
|
253
|
+
# We can't use the setter before MailClient is loaded
|
254
|
+
self.mail_adapter = self.mail_adapter
|
239
255
|
end
|
240
256
|
|
241
257
|
# Create a JSON web token with the provided payload
|
@@ -294,9 +310,6 @@ module MnoEnterprise
|
|
294
310
|
|
295
311
|
# Adapter
|
296
312
|
c.use Faraday::Adapter::NetHttpNoProxy
|
297
|
-
|
298
|
-
# Error Handling
|
299
|
-
c.use Her::Middleware::MnoeRaiseError
|
300
313
|
end
|
301
314
|
end
|
302
315
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
module MailAdapters
|
3
|
+
# @abstract Subclass and override {#client} and {#deliver} to implement
|
4
|
+
# a custom Mailer Adapter.
|
5
|
+
class Adapter
|
6
|
+
class << self
|
7
|
+
# Store the list of emails that are pending to be sent.
|
8
|
+
# @note Only used for testing
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# expect { some_action }.to change(Adapter.base_deliveries,:count).by(1)
|
12
|
+
#
|
13
|
+
# @return [Array]
|
14
|
+
def base_deliveries
|
15
|
+
@base_deliveries ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
# Check whether mailers are in test mode or not.
|
19
|
+
# Emails should not be sent in test mode.
|
20
|
+
#
|
21
|
+
# @return [Boolean]
|
22
|
+
def test?
|
23
|
+
(Rails.configuration.action_mailer.delivery_method || '').to_sym == :test
|
24
|
+
end
|
25
|
+
|
26
|
+
def client
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
# Send a template
|
31
|
+
#
|
32
|
+
# @param [String] template the immutable name of the template to send
|
33
|
+
#
|
34
|
+
# @param [Hash] from a hash describing the sender
|
35
|
+
# @option from [String] :name optional from name to be used
|
36
|
+
# @option from [String] :email the sender email address
|
37
|
+
#
|
38
|
+
# @param [Array, Hash] to an array or hash describing the recipient
|
39
|
+
# @option to [String] :name optional recipient name
|
40
|
+
# @option to [String] :email the recipient email address
|
41
|
+
#
|
42
|
+
# @param [Hash] vars substitution variables
|
43
|
+
# @param [Hash] opts additional parameters to pass to the client
|
44
|
+
#
|
45
|
+
def deliver(template,from,to,vars = {},opts = {})
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
gem 'mandrill-api', '~> 1.0.53'
|
2
|
+
require 'mandrill'
|
3
|
+
|
4
|
+
module MnoEnterprise
|
5
|
+
module MailAdapters
|
6
|
+
class MandrillAdapter < Adapter
|
7
|
+
class << self
|
8
|
+
# Return a mandrill client configured with the right API key
|
9
|
+
def client
|
10
|
+
@client ||= Mandrill::API.new(ENV['MANDRILL_API_KEY'] || MnoEnterprise.mandrill_key)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Send a template
|
14
|
+
# @see Adapter#deliver
|
15
|
+
def deliver(template, from, to, vars={}, opts={})
|
16
|
+
# Prepare message from args
|
17
|
+
message = { from_name: from[:name], from_email: from[:email]}
|
18
|
+
message[:to] = [to].flatten.map { |t| {name: t[:name], email: t[:email], type: (t[:type] || :to) } }
|
19
|
+
message[:global_merge_vars] = vars.map { |k,v| {name: k.to_s, content: v} }
|
20
|
+
|
21
|
+
# Merge additional mandrill options
|
22
|
+
message.merge!(opts)
|
23
|
+
|
24
|
+
self.send_template(template,[],message)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Send the provided template with options
|
28
|
+
# MandrillClient.send_template(template_name(string), template_content(array), message(hash))
|
29
|
+
def send_template(*args)
|
30
|
+
if self.test?
|
31
|
+
self.base_deliveries.push(args)
|
32
|
+
else
|
33
|
+
self.client.messages.send_template(*args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
module MailAdapters
|
3
|
+
# SMTP Adapter for MnoEnterprise::MailClient
|
4
|
+
class SmtpAdapter < Adapter
|
5
|
+
class << self
|
6
|
+
# Return a smtp client configured with the SMTP settings
|
7
|
+
# @return [SmtpClient]
|
8
|
+
def client
|
9
|
+
@client = MnoEnterprise::SmtpClient.send :new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Send a template
|
13
|
+
# @See Adapter#deliver
|
14
|
+
def deliver(template, from, to, vars={}, opts={})
|
15
|
+
client.deliver(template, from, to, vars, opts).deliver
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
gem 'sparkpost'
|
2
|
+
require 'sparkpost'
|
3
|
+
|
4
|
+
module MnoEnterprise
|
5
|
+
module MailAdapters
|
6
|
+
# SparkPost Adapter for MnoEnterprise::MailClient
|
7
|
+
class SparkpostAdapter < Adapter
|
8
|
+
class << self
|
9
|
+
# Return a sparkpost client configured with the right API key
|
10
|
+
# api key is set in ENV through ENV['SPARKPOST_API_KEY']
|
11
|
+
# @return [SparkPost::Client]
|
12
|
+
def client
|
13
|
+
@client ||= SparkPost::Client.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# Send a template
|
17
|
+
# @see Adapter#deliver
|
18
|
+
def deliver(template, from, to, vars={}, opts={})
|
19
|
+
# Prepare message from args
|
20
|
+
message = {
|
21
|
+
recipients: prepare_recipients(to),
|
22
|
+
content: {
|
23
|
+
from: from,
|
24
|
+
template_id: template
|
25
|
+
},
|
26
|
+
substitution_data: vars
|
27
|
+
}
|
28
|
+
|
29
|
+
# Merge additional options
|
30
|
+
message.merge!(opts)
|
31
|
+
|
32
|
+
# Send
|
33
|
+
send_template(template,[],message)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Send the provided template with options
|
37
|
+
# SparkpostClient.send_template(template_name(string), template_content(array), message(hash))
|
38
|
+
def send_template(template_name, _, message)
|
39
|
+
if test?
|
40
|
+
base_deliveries.push([template_name, message])
|
41
|
+
else
|
42
|
+
message[:content][:template_id] = template_name
|
43
|
+
client.transmission.send_payload(message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# TODO: Use delegate?
|
50
|
+
def prepare_recipients(recipients)
|
51
|
+
client.transmission.prepare_recipients(recipients)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
module MailAdapters
|
3
|
+
# Test Adapter for MnoEnterprise::MailClient
|
4
|
+
# Add messages to an internal array instead of sending them
|
5
|
+
class TestAdapter < Adapter
|
6
|
+
class << self
|
7
|
+
# Send a template
|
8
|
+
# @see Adapter#deliver
|
9
|
+
def deliver(*args)
|
10
|
+
send_template(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Send the provided template with options
|
14
|
+
# SparkpostClient.send_template(template_name(string), template_content(array), message(hash))
|
15
|
+
def send_template(*args)
|
16
|
+
base_deliveries.push(*args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
# Abstract the email sending logic
|
3
|
+
#
|
4
|
+
class MailClient
|
5
|
+
cattr_reader(:adapter)
|
6
|
+
|
7
|
+
# Specify the mail adapter. The default email adapter is the :mandrill adapter.
|
8
|
+
def self.adapter=(name_or_adapter)
|
9
|
+
@@adapter = \
|
10
|
+
case name_or_adapter
|
11
|
+
when Symbol, String
|
12
|
+
load_adapter(name_or_adapter)
|
13
|
+
else
|
14
|
+
name_or_adapter if name_or_adapter.respond_to?(:deliver)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# @see Adapter#deliver
|
19
|
+
def self.deliver(*args)
|
20
|
+
adapter.deliver(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def self.load_adapter(name)
|
25
|
+
"MnoEnterprise::MailAdapters::#{name.to_s.camelize}Adapter".constantize
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'action_mailer/railtie'
|
2
|
+
|
3
|
+
module MnoEnterprise
|
4
|
+
# Base class (instantiable) for SMTP adapter
|
5
|
+
class SmtpClient < ActionMailer::Base
|
6
|
+
# Send SMTP template - terminal mailing part
|
7
|
+
def deliver(template, from, to, vars={}, opts={})
|
8
|
+
@info = vars
|
9
|
+
@info[:company] = from[:name]
|
10
|
+
|
11
|
+
mail(
|
12
|
+
from: format_sender(from),
|
13
|
+
to: to[:email],
|
14
|
+
subject: humanize(template),
|
15
|
+
template_path: 'system_notifications',
|
16
|
+
template_name: template
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns Actionmailer-compliant :from string
|
21
|
+
# @Format : "Sender name <sender@email.com>"
|
22
|
+
def format_sender(from)
|
23
|
+
"#{from[:name]} <#{from[:email]}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns humanized template subject
|
27
|
+
# @i.e. "reset-password-instructions" to "Reset password instructions"
|
28
|
+
def humanize(template_slug)
|
29
|
+
template_slug.tr("-", "_").humanize
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -22,7 +22,7 @@ FactoryGirl.define do
|
|
22
22
|
stack 'cube'
|
23
23
|
terms_url "http://opensource.org/licenses/MIT"
|
24
24
|
appinfo { {} }
|
25
|
-
|
25
|
+
sequence(:rank) { |n| n }
|
26
26
|
pricing_plans {{
|
27
27
|
'default' =>[{name: 'Monthly Plan', price: '20.0', currency: 'AUD', factor: '/month'}]
|
28
28
|
}}
|
@@ -41,5 +41,4 @@ FactoryGirl.define do
|
|
41
41
|
# Properly build the resource with Her
|
42
42
|
initialize_with { new(attributes).tap { |e| e.clear_attribute_changes! } }
|
43
43
|
end
|
44
|
-
|
45
44
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
|
3
|
-
|
4
|
-
# TODO: Remove once all mnohub are migrated to newer versions
|
5
|
-
factory :old_tenant, class: MnoEnterprise::Tenant do
|
3
|
+
factory :tenant, class: MnoEnterprise::Tenant do
|
6
4
|
last_portfolio_amount Money.new(65644,'AUD')
|
7
5
|
last_customers_invoicing_amount Money.new(687994,'AUD')
|
8
6
|
last_customers_outstanding_amount Money.new(178986,'AUD')
|
@@ -11,8 +9,4 @@ FactoryGirl.define do
|
|
11
9
|
# Properly build the resource with Her
|
12
10
|
initialize_with { new(attributes).tap { |e| e.clear_attribute_changes! } }
|
13
11
|
end
|
14
|
-
|
15
|
-
factory :tenant, parent: :old_tenant do
|
16
|
-
current_billing_amount Money.new(123456, 'AUD')
|
17
|
-
end
|
18
12
|
end
|
@@ -124,8 +124,7 @@ module MnoEnterpriseApiTestHelper
|
|
124
124
|
|
125
125
|
# Response
|
126
126
|
c.use Her::Middleware::MnoeApiV1ParseJson
|
127
|
-
|
128
|
-
|
127
|
+
|
129
128
|
# Add stubs on the test adapter
|
130
129
|
c.use MnoeFaradayTestAdapter do |receiver|
|
131
130
|
@_stub_list.each do |key,stub|
|
@@ -3,76 +3,5 @@ require 'rails_helper'
|
|
3
3
|
module MnoEnterprise
|
4
4
|
RSpec.describe Her::Model::Relation do
|
5
5
|
pending "add specs for Her::Model::Relation monkey patch: #{__FILE__}"
|
6
|
-
|
7
|
-
before(:all) { Object.const_set('DummyClass', Class.new).send(:include, Her::Model) }
|
8
|
-
let(:dummy_class) { DummyClass }
|
9
|
-
|
10
|
-
describe '.where' do
|
11
|
-
it 'adds the filter to params[:filter]' do
|
12
|
-
rel = Her::Model::Relation.new(dummy_class).where('uid.in' => [1, 2], 'foo' => 'bar')
|
13
|
-
expect(rel.params[:filter]).to eq('uid.in' => [1, 2], 'foo' => 'bar')
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'replaces empty array values with nil' do
|
17
|
-
rel = Her::Model::Relation.new(dummy_class).where('id.in' => [])
|
18
|
-
expect(rel.params[:filter]).to eq('id.in' => nil)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# We mostly test our request expectations
|
23
|
-
describe '.first_or_create' do
|
24
|
-
let(:relation) { Her::Model::Relation.new(dummy_class) }
|
25
|
-
subject { relation.where(foo: 'bar').first_or_create(baz: 'bar') }
|
26
|
-
|
27
|
-
context 'when matching record' do
|
28
|
-
let(:record) { dummy_class.new(foo: 'bar') }
|
29
|
-
before do
|
30
|
-
expect(dummy_class).to receive(:request).with(hash_including(filter: {foo: 'bar'}, _method: :get)).and_return([record])
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'returns the record' do
|
34
|
-
expect(subject).to eq(record)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'when no matching record' do
|
39
|
-
before do
|
40
|
-
expect(dummy_class).to receive(:request).with(hash_including(filter: {foo: 'bar'}, _method: :get)).and_return([])
|
41
|
-
expect(dummy_class).to receive(:request).with(hash_including(foo: 'bar', baz: 'bar', _method: :post)).and_return(dummy_class.new)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'creates a new record' do
|
45
|
-
expect(subject).to eq(dummy_class.new(foo: 'bar', baz: 'bar'))
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# We mostly test our request expectations
|
51
|
-
describe '.first_or_initialize' do
|
52
|
-
let(:relation) { Her::Model::Relation.new(dummy_class) }
|
53
|
-
subject { relation.where(foo: 'bar').first_or_initialize(baz: 'bar') }
|
54
|
-
|
55
|
-
context 'when matching record' do
|
56
|
-
let(:record) { dummy_class.new(foo: 'bar') }
|
57
|
-
before do
|
58
|
-
expect(dummy_class).to receive(:request).with(hash_including(filter: {foo: 'bar'}, _method: :get)).and_return([record])
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'returns the record' do
|
62
|
-
expect(subject).to eq(record)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'when no matching record' do
|
67
|
-
before do
|
68
|
-
expect(dummy_class).to receive(:request).with(hash_including(filter: {foo: 'bar'}, _method: :get)).and_return([])
|
69
|
-
# No POST stub
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'build a new record' do
|
73
|
-
expect(subject).to eq(dummy_class.new(foo: 'bar', baz: 'bar'))
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
6
|
end
|
78
7
|
end
|