detour 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -1
  3. data/.travis.yml +6 -2
  4. data/Gemfile +5 -0
  5. data/README.md +41 -132
  6. data/Rake.md +108 -0
  7. data/Rakefile +21 -1
  8. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  9. data/app/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  10. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  11. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  12. data/app/assets/images/detour/.gitkeep +0 -0
  13. data/app/assets/javascripts/detour/application.js +16 -0
  14. data/app/assets/javascripts/detour/bootstrap.js +2006 -0
  15. data/app/assets/javascripts/detour/delete_feature.js +13 -0
  16. data/app/assets/javascripts/detour/delete_flag.js +13 -0
  17. data/app/assets/javascripts/detour/modals.js +3 -0
  18. data/app/assets/javascripts/detour/tooltips.js +3 -0
  19. data/app/assets/stylesheets/detour/application.css +14 -0
  20. data/app/assets/stylesheets/detour/bootstrap.css +7112 -0
  21. data/app/assets/stylesheets/detour/main.css +49 -0
  22. data/app/controllers/detour/application_controller.rb +12 -0
  23. data/app/controllers/detour/features_controller.rb +19 -0
  24. data/app/controllers/detour/flaggable_flags_controller.rb +90 -0
  25. data/app/controllers/detour/flags_controller.rb +18 -0
  26. data/app/helpers/detour/application_helper.rb +32 -0
  27. data/app/helpers/detour/flaggable_flags_helper.rb +5 -0
  28. data/app/helpers/detour/flags_helper.rb +7 -0
  29. data/app/models/detour/concerns/countable_flag.rb +19 -0
  30. data/app/models/detour/concerns/flag_actions.rb +141 -0
  31. data/app/models/detour/concerns/matchers.rb +73 -0
  32. data/app/models/detour/feature.rb +81 -0
  33. data/{lib → app/models}/detour/flag.rb +8 -2
  34. data/app/models/detour/flag_in_flag.rb +12 -0
  35. data/app/models/detour/group_flag.rb +13 -0
  36. data/{lib → app/models}/detour/opt_out_flag.rb +4 -2
  37. data/app/models/detour/percentage_flag.rb +9 -0
  38. data/app/views/detour/application/index.html.erb +0 -0
  39. data/app/views/detour/features/_errors.html.erb +11 -0
  40. data/app/views/detour/features/_success.html.erb +1 -0
  41. data/app/views/detour/features/error.js.erb +5 -0
  42. data/app/views/detour/features/success.js.erb +1 -0
  43. data/app/views/detour/flaggable_flags/_errors.html.erb +11 -0
  44. data/app/views/detour/flaggable_flags/_flaggable_flag.html.erb +11 -0
  45. data/app/views/detour/flaggable_flags/error.js.erb +5 -0
  46. data/app/views/detour/flaggable_flags/index.html.erb +34 -0
  47. data/app/views/detour/flaggable_flags/success.js.erb +1 -0
  48. data/app/views/detour/flags/_feature_form.html.erb +38 -0
  49. data/app/views/detour/flags/index.html.erb +76 -0
  50. data/app/views/detour/shared/_nav.html.erb +28 -0
  51. data/app/views/detour/shared/_spacer_cells.html.erb +3 -0
  52. data/app/views/layouts/detour/application.html.erb +29 -0
  53. data/config/routes.rb +16 -0
  54. data/detour.gemspec +15 -14
  55. data/lib/detour/acts_as_flaggable.rb +42 -3
  56. data/lib/detour/configuration.rb +35 -0
  57. data/lib/detour/engine.rb +5 -0
  58. data/lib/detour/flag_form.rb +87 -0
  59. data/lib/detour/version.rb +1 -1
  60. data/lib/detour.rb +10 -14
  61. data/lib/generators/templates/migration.rb +2 -0
  62. data/lib/tasks/detour.rake +16 -16
  63. data/script/rails +8 -0
  64. data/spec/controllers/detour/application_controller_spec.rb +15 -0
  65. data/spec/controllers/detour/features_controller_spec.rb +51 -0
  66. data/spec/controllers/detour/flaggable_flags_controller_spec.rb +100 -0
  67. data/spec/controllers/detour/flags_controller_spec.rb +77 -0
  68. data/spec/dummy/README.rdoc +261 -0
  69. data/spec/dummy/Rakefile +7 -0
  70. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  71. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  72. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  73. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  74. data/spec/dummy/app/mailers/.gitkeep +0 -0
  75. data/spec/dummy/app/models/.gitkeep +0 -0
  76. data/spec/dummy/app/models/user.rb +5 -0
  77. data/spec/dummy/app/models/widget.rb +5 -0
  78. data/spec/dummy/app/views/application/index.html.erb +22 -0
  79. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  80. data/spec/dummy/config/application.rb +65 -0
  81. data/spec/dummy/config/boot.rb +10 -0
  82. data/spec/dummy/config/database.yml +19 -0
  83. data/spec/dummy/config/environment.rb +5 -0
  84. data/spec/dummy/config/environments/development.rb +37 -0
  85. data/spec/dummy/config/environments/production.rb +67 -0
  86. data/spec/dummy/config/environments/test.rb +37 -0
  87. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/spec/dummy/config/initializers/detour.rb +36 -0
  89. data/spec/dummy/config/initializers/inflections.rb +15 -0
  90. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  91. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  92. data/spec/dummy/config/initializers/session_store.rb +8 -0
  93. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  94. data/spec/dummy/config/locales/en.yml +5 -0
  95. data/spec/dummy/config/routes.rb +4 -0
  96. data/spec/dummy/config.ru +4 -0
  97. data/spec/dummy/db/migrate/20131218015844_create_users.rb +10 -0
  98. data/spec/dummy/db/migrate/20131218023124_create_widgets.rb +9 -0
  99. data/spec/dummy/db/migrate/20131218055352_add_user_id_to_widgets.rb +6 -0
  100. data/spec/dummy/db/migrate/20131221052201_setup_detour.rb +32 -0
  101. data/spec/dummy/db/schema.rb +59 -0
  102. data/spec/dummy/db/seeds.rb +10 -0
  103. data/spec/dummy/lib/assets/.gitkeep +0 -0
  104. data/spec/dummy/log/.gitkeep +0 -0
  105. data/spec/dummy/public/404.html +26 -0
  106. data/spec/dummy/public/422.html +26 -0
  107. data/spec/dummy/public/500.html +25 -0
  108. data/spec/dummy/public/favicon.ico +0 -0
  109. data/spec/dummy/script/rails +6 -0
  110. data/spec/factories/feature.rb +5 -0
  111. data/spec/factories/flag_in_flag.rb +6 -0
  112. data/spec/factories/group_flag.rb +7 -0
  113. data/spec/factories/opt_out_flag.rb +6 -0
  114. data/spec/factories/percentage_flag.rb +7 -0
  115. data/spec/factories/user.rb +6 -0
  116. data/spec/factories/widget.rb +5 -0
  117. data/spec/features/features_spec.rb +70 -0
  118. data/spec/features/flag_in_flags_spec.rb +118 -0
  119. data/spec/features/group_flags_spec.rb +49 -0
  120. data/spec/features/home_page_spec.rb +11 -0
  121. data/spec/features/opt_out_flags_spec.rb +105 -0
  122. data/spec/features/percentage_flags_spec.rb +63 -0
  123. data/spec/integration/group_rollout_spec.rb +1 -1
  124. data/spec/lib/detour/acts_as_flaggable_spec.rb +45 -0
  125. data/spec/lib/detour/configuration_spec.rb +23 -0
  126. data/spec/lib/detour/flag_form_spec.rb +84 -0
  127. data/spec/lib/{active_record/rollout → detour}/flaggable_spec.rb +19 -19
  128. data/spec/lib/tasks/{detour_rake_spec.rb → detour_spec.rb} +54 -54
  129. data/spec/{lib/active_record/rollout → models/detour}/feature_spec.rb +93 -67
  130. data/spec/models/detour/flag_in_flag_spec.rb +38 -0
  131. data/spec/{lib/active_record/rollout → models/detour}/flag_spec.rb +1 -1
  132. data/spec/models/detour/opt_out_flag_spec.rb +38 -0
  133. data/spec/{lib/active_record/rollout → models/detour}/percentage_flag_spec.rb +1 -1
  134. data/spec/spec_helper.rb +41 -21
  135. data/spec/support/shared_contexts/rake.rb +4 -14
  136. metadata +278 -95
  137. data/lib/detour/feature.rb +0 -312
  138. data/lib/detour/flaggable_flag.rb +0 -10
  139. data/lib/detour/group_flag.rb +0 -8
  140. data/lib/detour/percentage_flag.rb +0 -11
  141. data/spec/lib/active_record/rollout/acts_as_flaggable_spec.rb +0 -31
  142. data/spec/lib/active_record/rollout/flaggable_flag_spec.rb +0 -9
  143. data/spec/lib/active_record/rollout/opt_out_flag_spec.rb +0 -9
  144. data/spec/support/schema.rb +0 -13
  145. /data/lib/generators/{active_record_rollout_generator.rb → detour_generator.rb} +0 -0
  146. /data/lib/generators/templates/{active_record_rollout.rb → detour.rb} +0 -0
  147. /data/spec/{lib/active_record/rollout → models/detour}/group_flag_spec.rb +0 -0
@@ -1,312 +0,0 @@
1
- # Represents an individual feature that may be rolled out to a set of records
2
- # via individual flags, percentages, or defined groups.
3
- class Detour::Feature < ActiveRecord::Base
4
- # A hash representing the groups that have been defined.
5
- @defined_groups = {}
6
-
7
- # Directories to grep for feature tests
8
- @grep_dirs = []
9
-
10
- self.table_name = :detour_features
11
-
12
- has_many :flaggable_flags
13
- has_many :group_flags
14
- has_many :percentage_flags
15
- has_many :opt_out_flags
16
- has_many :flags, dependent: :destroy
17
-
18
- validates :name, presence: true, uniqueness: true
19
-
20
- attr_accessible :name
21
-
22
- # Returns an instance variable intended to hold an array of the lines of code
23
- # that this feature appears on.
24
- #
25
- # @return [Array<String>] The lines that this rollout appears on (if
26
- # {Detour::Feature.all_with_lines} has already been called).
27
- def lines
28
- @lines ||= []
29
- end
30
-
31
- # Determines whether or not the given instance has had the feature rolled out
32
- # to it either via direct flagging-in, percentage, or by group membership.
33
- #
34
- # @example
35
- # feature.match?(current_user)
36
- #
37
- # @param [ActiveRecord::Base] instance A record to be tested for feature
38
- # rollout.
39
- #
40
- # @return Whether or not the given instance has the feature rolled out to it.
41
- def match?(instance)
42
- match_id?(instance) || match_percentage?(instance) || match_groups?(instance)
43
- end
44
-
45
- # Determines whether or not the given instance has had the feature rolled out
46
- # to it via direct flagging-in.
47
- #
48
- # @example
49
- # feature.match_id?(current_user)
50
- #
51
- # @param [ActiveRecord::Base] instance A record to be tested for feature
52
- # rollout.
53
- #
54
- # @return Whether or not the given instance has the feature rolled out to it
55
- # via direct flagging-in.
56
- def match_id?(instance)
57
- flaggable_flags.where(flaggable_type: instance.class.to_s, flaggable_id: instance.id).any?
58
- end
59
-
60
- # Determines whether or not the given instance has had the feature rolled out
61
- # to it via percentage.
62
- #
63
- # @example
64
- # feature.match_percentage?(current_user)
65
- #
66
- # @param [ActiveRecord::Base] instance A record to be tested for feature
67
- # rollout.
68
- #
69
- # @return Whether or not the given instance has the feature rolled out to it
70
- # via direct percentage.
71
- def match_percentage?(instance)
72
- flag = percentage_flags.find(:first, conditions: ["flaggable_type = ?", instance.class.to_s])
73
- percentage = flag ? flag.percentage : 0
74
-
75
- instance.id % 10 < percentage / 10
76
- end
77
-
78
- # Determines whether or not the given instance has had the feature rolled out
79
- # to it via group membership.
80
- #
81
- # @example
82
- # feature.match_groups?(current_user)
83
- #
84
- # @param [ActiveRecord::Base] instance A record to be tested for feature
85
- # rollout.
86
- #
87
- # @return Whether or not the given instance has the feature rolled out to it
88
- # via direct group membership.
89
- def match_groups?(instance)
90
- klass = instance.class.to_s
91
-
92
- return unless self.class.defined_groups[klass]
93
-
94
- group_names = group_flags.find_all_by_flaggable_type(klass).collect(&:group_name)
95
-
96
- self.class.defined_groups[klass].collect { |group_name, block|
97
- block.call(instance) if group_names.include? group_name
98
- }.any?
99
- end
100
-
101
- class << self
102
- # Returns the defined groups.
103
- def defined_groups
104
- @defined_groups
105
- end
106
-
107
- # Returns the default flaggable class.
108
- def default_flaggable_class_name
109
- @default_flaggable_class_name
110
- end
111
-
112
- # Sets the default flaggable class.
113
- def default_flaggable_class_name=(klass)
114
- @default_flaggable_class_name = klass
115
- end
116
-
117
- # A list of directories to search through when finding feature checks.
118
- def grep_dirs
119
- @grep_dirs
120
- end
121
-
122
- # Set the list of directories to search through when finding feature checks.
123
- def grep_dirs=(grep_dirs)
124
- @grep_dirs = grep_dirs
125
- end
126
-
127
- # Return an array of both every feature in the database as well as every
128
- # feature that is checked for in `@grep_dirs`. Features that are checked
129
- # for but not persisted will be returned as unpersisted instances of this
130
- # class. Each instance returned will have its `@lines` set to an array
131
- # containing every line in `@grep_dirs` where it is checked for.
132
- #
133
- # @return [Array<Detour::Feature>] Every persisted and
134
- # checked-for feature.
135
- def all_with_lines
136
- obj = all.each_with_object({}) { |feature, obj| obj[feature.name] = feature }
137
-
138
- Dir[*@grep_dirs].each do |path|
139
- next if File.directory? path
140
-
141
- File.open path do |file|
142
- file.each_line.with_index(1) do |line, i|
143
- line.scan(/\.has_feature\?\s*\(*:(\w+)/).each do |match|
144
- match = match[0]
145
- obj[match] ||= find_or_initialize_by_name(match)
146
- obj[match].lines << "#{path}#L#{i}"
147
- end
148
- end
149
- end
150
- end
151
-
152
- obj.values
153
- end
154
-
155
- # Add a record to the given feature. If the feature is not found, an
156
- # ActiveRecord::RecordNotFound will be raised.
157
- #
158
- # @example
159
- # Detour::Feature.add_record_to_feature user, :new_ui
160
- #
161
- # @param [ActiveRecord::Base] record A record to add the feature to.
162
- # @param [String,Symbol] feature_name The feature to be added to the record.
163
- #
164
- # @return [Detour::Flag] The
165
- # {Detour::Flag Flag} created.
166
- def add_record_to_feature(record, feature_name)
167
- feature = find_by_name!(feature_name)
168
- feature.flaggable_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).first_or_create!
169
- end
170
-
171
- # Remove a record from the given feature. If the feature is not found, an
172
- # ActiveRecord::RecordNotFound will be raised.
173
- #
174
- # @example
175
- # Detour::Feature.remove_record_from_feature user, :new_ui
176
- #
177
- # @param [ActiveRecord::Base] record A record to remove the feature from.
178
- # @param [String,Symbol] feature_name The feature to be removed from the
179
- # record.
180
- def remove_record_from_feature(record, feature_name)
181
- feature = find_by_name!(feature_name)
182
- feature.flaggable_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).destroy_all
183
- end
184
-
185
- # Opt the given record out of a feature. If the feature is not found, an
186
- # ActiveRecord::RecordNotFound will be raised. An opt out ensures that no
187
- # matter what, `record.rollout?(:rollout)` will always return false for any
188
- # opted-out-of features.
189
- #
190
- # @param [ActiveRecord::Base] record A record to opt out of the feature.
191
- # @param [String,Symbol] feature_name The feature to be opted out of.
192
- #
193
- # @example
194
- # Detour::Feature.opt_record_out_of_feature user, :new_ui
195
- #
196
- # @return [Detour::OptOut] The
197
- # {Detour::OptOut OptOut} created.
198
- def opt_record_out_of_feature(record, feature_name)
199
- feature = find_by_name!(feature_name)
200
- feature.opt_out_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).first_or_create!
201
- end
202
-
203
- # Remove any opt out for the given record out of a feature. If the feature
204
- # is not found, an ActiveRecord::RecordNotFound will be raised.
205
- #
206
- # @example
207
- # Detour::Feature.un_opt_record_out_of_feature user, :new_ui
208
- #
209
- # @param [ActiveRecord::Base] record A record to un-opt-out of the feature.
210
- # @param [String,Symbol] feature_name The feature to be un-opted-out of.
211
- def un_opt_record_out_of_feature(record, feature_name)
212
- feature = find_by_name!(feature_name)
213
- feature.opt_out_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).destroy_all
214
- end
215
-
216
- # Add a group to the given feature. If the feature is not found, an
217
- # ActiveRecord::RecordNotFound will be raised.
218
- #
219
- # @example
220
- # Detour::Feature.add_group_to_feature "User", "admin", :delete_records
221
- #
222
- # @param [String] flaggable_type The class (as a string) that the group
223
- # should be associated with.
224
- # @param [String] group_name The name of the group to have the feature
225
- # added to it.
226
- # @param [String,Symbol] feature_name The feature to be added to the group.
227
- #
228
- # @return [Detour::Flag] The
229
- # {Detour::Flag Flag} created.
230
- def add_group_to_feature(flaggable_type, group_name, feature_name)
231
- feature = find_by_name!(feature_name)
232
- feature.group_flags.where(flaggable_type: flaggable_type, group_name: group_name).first_or_create!
233
- end
234
-
235
- # Remove a group from agiven feature. If the feature is not found, an
236
- # ActiveRecord::RecordNotFound will be raised.
237
- #
238
- # @example
239
- # Detour::Feature.remove_group_from_feature "User", "admin", :delete_records
240
- #
241
- # @param [String] flaggable_type The class (as a string) that the group should
242
- # be removed from.
243
- # @param [String] group_name The name of the group to have the feature
244
- # removed from it.
245
- # @param [String,Symbol] feature_name The feature to be removed from the
246
- # group.
247
- def remove_group_from_feature(flaggable_type, group_name, feature_name)
248
- feature = find_by_name!(feature_name)
249
- feature.group_flags.where(flaggable_type: flaggable_type, group_name: group_name).destroy_all
250
- end
251
-
252
- # Add a percentage of records to the given feature. If the feature is not
253
- # found, an ActiveRecord::RecordNotFound will be raised.
254
- #
255
- # @example
256
- # Detour::Feature.add_percentage_to_feature "User", 75, :delete_records
257
- #
258
- # @param [String] flaggable_type The class (as a string) that the percetnage
259
- # should be associated with.
260
- # @param [Integer] percentage The percentage of `flaggable_type` records
261
- # that the feature will be available for.
262
- # @param [String,Symbol] feature_name The feature to be added to the
263
- # percentage of records.
264
- #
265
- # @return [Detour::Flag] The
266
- # {Detour::Flag Flag} created.
267
- def add_percentage_to_feature(flaggable_type, percentage, feature_name)
268
- feature = find_by_name!(feature_name)
269
-
270
- flag = feature.percentage_flags.where(flaggable_type: flaggable_type).first_or_initialize
271
- flag.update_attributes!(percentage: percentage)
272
- end
273
-
274
- # Remove any percentage flags for the given feature. If the feature is not
275
- # found, an ActiveRecord::RecordNotFound will be raised.
276
- #
277
- # @example
278
- # Detour::Feature.remove_percentage_from_feature "User", delete_records
279
- #
280
- # @param [String] flaggable_type The class (as a string) that the percetnage
281
- # should be removed from.
282
- # @param [String,Symbol] feature_name The feature to have the percentage
283
- # flag removed from.
284
- def remove_percentage_from_feature(flaggable_type, feature_name)
285
- feature = find_by_name!(feature_name)
286
- feature.percentage_flags.where(flaggable_type: flaggable_type).destroy_all
287
- end
288
-
289
- # Allows for methods of the form `define_user_group` that call the private
290
- # method `define_group_for_class`. A new group for any `User` records will
291
- # be created that rollouts can be attached to.
292
- #
293
- # @example
294
- # Detour::Feature.define_user_group :admins do |user|
295
- # user.admin?
296
- # end
297
- def method_missing(method, *args, &block)
298
- if /^define_(?<klass>[a-z0-9_]+)_group/ =~ method
299
- define_group_for_class(klass.classify, args[0], &block)
300
- else
301
- super
302
- end
303
- end
304
-
305
- private
306
-
307
- def define_group_for_class(klass, group_name, &block)
308
- @defined_groups[klass] ||= {}
309
- @defined_groups[klass][group_name] = block
310
- end
311
- end
312
- end
@@ -1,10 +0,0 @@
1
- # An individual record of a certain type may be flagged into a feature with
2
- # this class.
3
- class Detour::FlaggableFlag < Detour::Flag
4
- belongs_to :flaggable, polymorphic: true
5
-
6
- validates :flaggable_id, presence: true
7
- validates :feature_id, uniqueness: { scope: [:flaggable_type, :flaggable_id] }
8
-
9
- attr_accessible :flaggable
10
- end
@@ -1,8 +0,0 @@
1
- # A group of flaggable records of a given class may be flagged into a feature
2
- # with this class.
3
- class Detour::GroupFlag < Detour::Flag
4
- validates :group_name, presence: true
5
-
6
- attr_accessible :group_name
7
- validates :feature_id, uniqueness: { scope: [:flaggable_type, :group_name] }
8
- end
@@ -1,11 +0,0 @@
1
- # A percentage of flaggable records of a given class may be flagged into a feature
2
- # with this class.
3
- class Detour::PercentageFlag < Detour::Flag
4
- validates :percentage,
5
- presence: true,
6
- numericality: { greater_than: 0, less_than_or_equal_to: 100 }
7
-
8
- validates :feature_id, uniqueness: { scope: :flaggable_type }
9
-
10
- attr_accessible :percentage
11
- end
@@ -1,31 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Detour::ActsAsFlaggable do
4
- subject { User.new }
5
-
6
- it { should have_many :flaggable_flags }
7
- it { should have_many :opt_out_flags }
8
- it { should have_many(:features).through(:flaggable_flags) }
9
-
10
- it "includes Detour::Flaggable" do
11
- subject.class.ancestors.should include Detour::Flaggable
12
- end
13
-
14
- describe "#acts_as_flaggable" do
15
- context "when given a :find_by parameter" do
16
- class Foo < ActiveRecord::Base
17
- acts_as_flaggable find_by: :email
18
- end
19
-
20
- it "sets the appropriate class variable on the class" do
21
- Foo.instance_variable_get("@detour_flaggable_find_by").should eq :email
22
- end
23
- end
24
-
25
- context "when not given a :find_by parameter" do
26
- it "uses the default :id value for flaggable_find_by" do
27
- User.instance_variable_get("@detour_flaggable_find_by").should eq :id
28
- end
29
- end
30
- end
31
- end
@@ -1,9 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Detour::FlaggableFlag do
4
- it { should be_a Detour::Flag }
5
- it { should belong_to :flaggable }
6
- it { should validate_presence_of :flaggable_id }
7
- it { should allow_mass_assignment_of :flaggable }
8
- it { should validate_uniqueness_of :feature_id }
9
- end
@@ -1,9 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Detour::OptOutFlag do
4
- it { should be_a Detour::Flag }
5
- it { should belong_to :flaggable }
6
- it { should validate_presence_of :flaggable_id }
7
- it { should allow_mass_assignment_of :flaggable}
8
- it { should validate_uniqueness_of :feature_id }
9
- end
@@ -1,13 +0,0 @@
1
- ActiveRecord::Schema.define do
2
- self.verbose = false
3
-
4
- create_table :users, force: true do |t|
5
- t.string :name
6
- t.timestamps
7
- end
8
-
9
- create_table :organizations, force: true do |t|
10
- t.string :name
11
- t.timestamps
12
- end
13
- end