tenancy 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,179 @@
1
+ require "spec_helper"
2
+
3
+ if defined?(Mongoid)
4
+ describe "Tenancy::Scoping::Mongoid", mongoid: true do
5
+ let(:camyp) { Mongo::Portal.create(domain_name: "yp.com.kh") }
6
+ let(:panpages) { Mongo::Portal.create(domain_name: "panpages.com") }
7
+ let(:listing) { Mongo::Listing.create(name: "Listing 1", portal_id: camyp.id) }
8
+
9
+ describe Mongo::Listing do
10
+ it { should belong_to(:portal).of_type(Mongo::Portal) }
11
+
12
+ it { should validate_presence_of(:portal) }
13
+
14
+ it { should validate_uniqueness_of(:name).scoped_to(:portal_id).case_insensitive }
15
+
16
+ it "have default_scope with :portal_id field" do
17
+ Mongo::Portal.current = camyp
18
+
19
+ expect(Mongo::Listing.where(nil).selector).to eq({"is_active"=>true, "portal_id"=>Mongo::Portal.current_id})
20
+ end
21
+
22
+ it "doesn't have default_scope when it doesn't have current portal" do
23
+ Mongo::Portal.current = nil
24
+
25
+ expect(Mongo::Listing.where(nil).selector).to eq({"is_active"=>true})
26
+ end
27
+ end
28
+
29
+ describe Mongo::Communication do
30
+ it { should belong_to(:portal) }
31
+
32
+ it { should validate_presence_of(:portal) }
33
+
34
+ it { should belong_to(:listing) }
35
+
36
+ it { should validate_presence_of(:listing) }
37
+
38
+ it { should validate_uniqueness_of(:value).scoped_to(:portal_id, :listing_id) }
39
+
40
+ it "have default_scope with :portal_id field" do
41
+ Mongo::Portal.current = camyp
42
+ Mongo::Listing.current = listing
43
+
44
+ expect(Mongo::Communication.where(nil).selector).to eq({"is_active"=>true, "portal_id"=>Mongo::Portal.current_id, "listing_id"=>Mongo::Listing.current_id})
45
+ end
46
+
47
+ it "doesn't have default_scope when it doesn't have current portal and listing" do
48
+ Mongo::Portal.current = nil
49
+ Mongo::Listing.current = nil
50
+
51
+ expect(Mongo::Communication.where(nil).selector).to eq({"is_active"=>true})
52
+ end
53
+ end
54
+
55
+ describe Mongo::ExtraCommunication do
56
+ it { should belong_to(:portal).of_type(Mongo::Portal) }
57
+
58
+ it { should belong_to(:listing).of_type(Mongo::Listing) }
59
+
60
+ it "raise exception when passing two resources and options" do
61
+ expect { Mongo::ExtraCommunication.scope_to(:portal, :listing, class_name: "Mongo::Listing") }.to raise_error(ArgumentError)
62
+ end
63
+
64
+ it "uses the correct scope" do
65
+ listing2 = Mongo::Listing.create(name: "Name 2", portal: camyp)
66
+
67
+ Mongo::Portal.current = camyp
68
+ Mongo::Listing.current = listing2
69
+
70
+ extra_communication = Mongo::ExtraCommunication.new
71
+ expect(extra_communication.listing_id).to eq(listing2.id)
72
+ expect(extra_communication.portal_id).to eq(camyp.id)
73
+ end
74
+ end
75
+
76
+ describe "belongs_to method override" do
77
+ before(:each) { Mongo::Portal.current = camyp }
78
+
79
+ it "reload belongs_to when passes true" do
80
+ listing.portal.domain_name = "abc.com"
81
+
82
+ expect(listing.portal(true).object_id).not_to eq(Mongo::Portal.current.object_id)
83
+ end
84
+
85
+ it "doesn't reload belongs_to" do
86
+ listing.portal.domain_name = "abc.com"
87
+
88
+ expect(listing.portal.object_id).to eq(Mongo::Portal.current.object_id)
89
+ end
90
+
91
+ it "returns different object" do
92
+ listing.portal_id = panpages.id
93
+
94
+ expect(listing.portal.object_id).not_to eq(Mongo::Portal.current.object_id)
95
+ end
96
+
97
+ it "doesn't touch db" do
98
+ current_listing = listing
99
+
100
+ Mongo::Portal.store_in session: ""
101
+ expect(current_listing.portal.object_id).to eq(Mongo::Portal.current.object_id)
102
+ Mongo::Portal.store_in session: "default"
103
+ end
104
+ end
105
+
106
+ describe "#shard_key_selector override" do
107
+ before(:each) { Mongo::Portal.current = camyp }
108
+
109
+ it "returns with current_portal" do
110
+ expect(Mongo::Communication.new.shard_key_selector).to eq({"portal_id"=>camyp.id})
111
+ end
112
+
113
+ it "returns with current_listing" do
114
+ Mongo::Listing.current = listing
115
+
116
+ expect(Mongo::Communication.new.shard_key_selector).to eq({"portal_id"=>camyp.id, "listing_id"=>listing.id})
117
+ end
118
+
119
+ it "returns without :current_portal and :current_listing" do
120
+ Mongo::Portal.current = nil
121
+ Mongo::Listing.current = nil
122
+
123
+ expect(Mongo::Communication.new.shard_key_selector).to eq({})
124
+ end
125
+ end
126
+
127
+ describe "#tenant_scope" do
128
+ before(:each) { Mongo::Portal.current = camyp }
129
+
130
+ it "scopes only :current_portal" do
131
+ Mongo::Listing.current = listing
132
+
133
+ expect(Mongo::Communication.tenant_scope(:portal).selector).to eq({"is_active"=>true, "portal_id"=>Mongo::Portal.current_id})
134
+ end
135
+
136
+ it "scopes only :current_listing" do
137
+ Mongo::Listing.current = listing
138
+
139
+ expect(Mongo::Communication.tenant_scope(:listing).selector).to eq({"is_active"=>true, "listing_id"=>Mongo::Listing.current_id})
140
+ end
141
+
142
+ it "scopes only :current_listing and :current_portal" do
143
+ Mongo::Listing.current = listing
144
+
145
+ expect(Mongo::Communication.tenant_scope(:listing, :portal).selector).to eq(Mongo::Communication.where(nil).selector)
146
+ end
147
+
148
+ it "scopes nothing" do
149
+ Mongo::Listing.current = listing
150
+
151
+ expect(Mongo::Communication.tenant_scope(nil).selector).to eq({"is_active"=>true})
152
+ end
153
+ end
154
+
155
+ if ::Mongoid::VERSION.start_with?("3.1.")
156
+ describe "getter method override" do
157
+ before(:each) { Mongo::Portal.current = camyp }
158
+
159
+ it "returns the current portal_id" do
160
+ expect(Mongo::Listing.new.portal_id).to eq(camyp.id)
161
+ end
162
+
163
+ it "#portal_id returns nil" do
164
+ Mongo::Portal.current = nil
165
+
166
+ expect(Mongo::Listing.new.portal_id).to eq(nil)
167
+ end
168
+
169
+ it "returns its value for existing" do
170
+ listing = Mongo::Listing.create(name: "abcdef")
171
+ expect(listing.portal_id).to eq(camyp.id)
172
+
173
+ Mongo::Portal.current = nil
174
+ expect(listing.portal_id).to eq(camyp.id)
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -1,20 +1,44 @@
1
- require 'spec_helper'
2
- require 'tenancy/matchers'
1
+ require "spec_helper"
2
+ require "tenancy/matchers"
3
3
 
4
- describe Portal do
5
- it { should be_a_tenant }
6
- end
4
+ if defined?(ActiveRecord)
5
+ describe Portal do
6
+ it { should be_a_tenant }
7
+ end
7
8
 
8
- describe Listing do
9
- it { should be_a_tenant }
10
- end
9
+ describe Listing do
10
+ it { should be_a_tenant }
11
+ end
11
12
 
12
- describe ExtraCommunication do
13
- let(:camyp) { Portal.create(domain_name: 'yp.com.kh') }
14
- before { Portal.current = camyp }
13
+ describe ExtraCommunication do
14
+ let(:camyp) { Portal.create(domain_name: "yp.com.kh") }
15
+ before { Portal.current = camyp }
15
16
 
16
- it { should have_scope_to(:portal) }
17
- it { should have_scope_to(:portal).class_name('Portal') }
18
- it { should have_scope_to(:listing) }
19
- it { should have_scope_to(:listing).class_name('Listing') }
17
+ it { should have_scope_to(:portal) }
18
+ it { should have_scope_to(:portal).class_name("Portal") }
19
+ it { should have_scope_to(:listing) }
20
+ it { should have_scope_to(:listing).class_name("Listing") }
21
+ end
20
22
  end
23
+
24
+ if defined?(Mongoid)
25
+ module Mongo
26
+ describe Portal do
27
+ it { should be_a_tenant }
28
+ end
29
+
30
+ describe Listing do
31
+ it { should be_a_tenant }
32
+ end
33
+
34
+ describe ExtraCommunication do
35
+ let(:camyp) { Portal.create(domain_name: "yp.com.kh") }
36
+ before { Portal.current = camyp }
37
+
38
+ it { should have_scope_to(:portal) }
39
+ it { should have_scope_to(:portal).of_type(Mongo::Portal) }
40
+ it { should have_scope_to(:listing) }
41
+ it { should have_scope_to(:listing).of_type(Mongo::Listing) }
42
+ end
43
+ end
44
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,17 +1,68 @@
1
+ require "simplecov"
2
+ require "coveralls"
1
3
  require "codeclimate-test-reporter"
2
- CodeClimate::TestReporter.start
3
4
 
4
- require 'tenancy'
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ Coveralls::SimpleCov::Formatter,
7
+ SimpleCov::Formatter::HTMLFormatter,
8
+ CodeClimate::TestReporter::Formatter
9
+ ]
10
+
11
+ SimpleCov.start do
12
+ add_filter "/spec/"
13
+ end
14
+
15
+ require "pry"
16
+ require "database_cleaner"
17
+ require "logger"
18
+ require "tenancy"
5
19
 
6
20
  # active_record
7
- load File.dirname(__FILE__) + '/support/schema.rb'
8
- load File.dirname(__FILE__) + '/support/models.rb'
21
+ if Gem.loaded_specs["activerecord"]
22
+ load File.dirname(__FILE__) + "/support/active_record/schema.rb"
23
+ load File.dirname(__FILE__) + "/support/active_record/models.rb"
24
+ require "shoulda-matchers"
25
+ end
9
26
 
10
- require 'pry'
11
- require 'shoulda-matchers'
27
+ # mongoid
28
+ if Gem.loaded_specs["mongoid"]
29
+ load File.dirname(__FILE__) + "/support/mongoid/connection.rb"
30
+ load File.dirname(__FILE__) + "/support/mongoid/models.rb"
31
+ require "mongoid-rspec"
32
+ end
12
33
 
13
34
  RSpec.configure do |config|
14
35
  config.filter_run focus: true
15
36
  config.run_all_when_everything_filtered = true
16
37
  config.treat_symbols_as_metadata_keys_with_true_values = true
38
+
39
+ config.before(:suite) do
40
+ DatabaseCleaner.strategy = :truncation
41
+ end
42
+ config.include Mongoid::Matchers, mongoid: true if defined?(Mongoid)
43
+
44
+ config.around(:each) do |example|
45
+ if example.metadata[:log]
46
+ if defined?(ActiveRecord)
47
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
48
+ end
49
+ if defined?(Mongoid)
50
+ Mongoid.logger.level = Logger::DEBUG
51
+ Moped.logger.level = Logger::DEBUG
52
+ end
53
+ end
54
+ DatabaseCleaner.start
55
+ RequestStore.clear!
56
+
57
+ example.run
58
+
59
+ if defined?(ActiveRecord)
60
+ ActiveRecord::Base.logger = nil
61
+ end
62
+ if defined?(Mongoid)
63
+ Mongoid.logger.level = Logger::INFO
64
+ Moped.logger.level = Logger::INFO
65
+ end
66
+ DatabaseCleaner.clean
67
+ end
17
68
  end
@@ -7,7 +7,7 @@ class Listing < ActiveRecord::Base
7
7
  include Tenancy::ResourceScope
8
8
 
9
9
  default_scope -> { where(is_active: true) }
10
- scope_to :portal
10
+ scope_to :portal
11
11
  validates_uniqueness_in_scope :name, case_sensitive: false
12
12
  end
13
13
 
@@ -15,13 +15,13 @@ class Communication < ActiveRecord::Base
15
15
  include Tenancy::ResourceScope
16
16
 
17
17
  default_scope -> { where(is_active: true) }
18
- scope_to :portal, :listing
18
+ scope_to :portal, :listing
19
19
  validates_uniqueness_in_scope :value
20
20
  end
21
21
 
22
22
  class ExtraCommunication < ActiveRecord::Base
23
23
  include Tenancy::ResourceScope
24
24
 
25
- scope_to :portal, class_name: 'Portal'
26
- scope_to :listing, class_name: 'Listing'
27
- end
25
+ scope_to :portal, class_name: "Portal"
26
+ scope_to :listing, class_name: "Listing"
27
+ end
@@ -1,7 +1,6 @@
1
- require 'active_record'
2
- require 'logger'
1
+ require "active_record"
3
2
 
4
- ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'spec/test.sqlite3')
3
+ ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: "spec/test.sqlite3")
5
4
  ActiveRecord::Migration.verbose = false
6
5
 
7
6
  ActiveRecord::Schema.define do
@@ -35,4 +34,4 @@ ActiveRecord::Schema.define do
35
34
  t.references :portal
36
35
  t.timestamps
37
36
  end
38
- end
37
+ end
@@ -0,0 +1,3 @@
1
+ require "mongoid"
2
+
3
+ Mongoid.load! File.dirname(__FILE__) + "/mongoid.yml", :test
@@ -0,0 +1,44 @@
1
+ module Mongo
2
+ class Portal
3
+ include Mongoid::Document
4
+ include Tenancy::Resource
5
+
6
+ field :domain_name, type: String
7
+ end
8
+
9
+ class Listing
10
+ include Mongoid::Document
11
+ include Tenancy::Resource
12
+ include Tenancy::ResourceScope
13
+
14
+ field :name, type: String
15
+
16
+ default_scope -> { where(is_active: true) }
17
+ scope_to :portal, class_name: "Mongo::Portal"
18
+ validates_uniqueness_in_scope \
19
+ :name, case_sensitive: false
20
+ end
21
+
22
+ class Communication
23
+ include Mongoid::Document
24
+ include Tenancy::ResourceScope
25
+
26
+ field :value, type: String
27
+
28
+ default_scope -> { where(is_active: true) }
29
+ scope_to :portal, class_name: "Mongo::Portal"
30
+ scope_to :listing, class_name: "Mongo::Listing"
31
+ validates_uniqueness_in_scope \
32
+ :value
33
+ end
34
+
35
+ class ExtraCommunication
36
+ include Mongoid::Document
37
+ include Tenancy::ResourceScope
38
+
39
+ field :value, type: String
40
+
41
+ scope_to :portal, class_name: "Mongo::Portal"
42
+ scope_to :listing, class_name: "Mongo::Listing"
43
+ end
44
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ database: tenancy_mongoid_test
5
+ hosts:
6
+ - localhost:27017
data/tenancy.gemspec CHANGED
@@ -1,29 +1,26 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'tenancy/version'
4
+ require "tenancy/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "tenancy"
8
8
  spec.version = Tenancy::VERSION
9
- spec.authors = ["chamnap"]
9
+ spec.authors = ["Chamnap Chhorn"]
10
10
  spec.email = ["chamnapchhorn@gmail.com"]
11
- spec.description = %q{A simple multitenancy with activerecord through scoping}
12
- spec.summary = %q{A simple multitenancy with activerecord through scoping}
11
+ spec.description = %q{A simple multitenancy with activerecord/mongoid through scoping}
12
+ spec.summary = %q{A simple multitenancy with activerecord/mongoid through scoping}
13
13
  spec.homepage = "https://github.com/yoolk/tenancy"
14
14
  spec.license = "MIT"
15
15
 
16
+ spec.required_ruby_version = ">= 1.9.3"
17
+ spec.required_rubygems_version = ">= 1.8.11"
18
+
16
19
  spec.files = `git ls-files`.split($/)
17
20
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
21
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
22
  spec.require_paths = ["lib"]
20
23
 
21
- spec.add_development_dependency "rspec", "~> 2.12.0"
22
- spec.add_development_dependency "shoulda", "~> 3.5.0"
23
- spec.add_development_dependency "pry", "~> 0.9.12"
24
- spec.add_development_dependency "sqlite3", "~> 1.3.7"
25
- spec.add_development_dependency "rake"
26
-
27
- spec.add_dependency "activerecord", ">= 3.2.13"
24
+ spec.add_dependency "activesupport", ">= 3.2"
28
25
  spec.add_dependency "request_store", "~> 1.0.5"
29
- end
26
+ end