Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rubyversion: ['2.4', '2.5', '2.6', '2.7', '3.0']
rubyversion: ['2.7', '3.0', '3.1']
steps:
- uses: actions/checkout@v2
- name: set up ruby
Expand Down
4 changes: 1 addition & 3 deletions lib/toggles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ def init
path = Pathname.new(abspath).relative_path_from(top_level_p).to_s
features = path.split('/')[0..-2].inject(Feature.features) { |a, e| a[e.to_sym] ||= {} }
feature_key = File.basename(path, File.extname(path)).to_sym
features[feature_key] = Class.new(Feature::Base) do |c|
c.const_set(:PERMISSIONS, Feature::Permissions.new(abspath))
end
features[feature_key] = Feature::Permissions.from_yaml(abspath)
end

stbuf = File.stat(top_level)
Expand Down
1 change: 0 additions & 1 deletion lib/toggles/feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def self.disabled?(*sym, **criteria)
end

require 'toggles/constant_lookup'
require "toggles/feature/base"
require "toggles/feature/attribute"
require "toggles/feature/permissions"
require "toggles/feature/subject"
Expand Down
27 changes: 0 additions & 27 deletions lib/toggles/feature/base.rb

This file was deleted.

23 changes: 17 additions & 6 deletions lib/toggles/feature/permissions.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
require 'ostruct'
require 'forwardable'
require 'yaml'

class Feature::Permissions
Feature::Permissions = Struct.new(:rules) do
extend Forwardable

attr_reader :rules

def_delegators :rules, :all?, :keys

def initialize(path)
@rules = YAML.load(File.read(path))
def self.from_yaml(path)
new(
YAML.safe_load(File.read(path), permitted_classes: [Symbol])
)
end

def subjects
@subjects ||= keys.map(&:to_sym)
end

def valid_for?(entities)
raise Feature::Subject::Invalid, Feature::Subject.difference(subjects, entities.keys) unless subjects == entities.keys
unless subjects == entities.keys
raise Feature::Subject::Invalid, Feature::Subject.difference(subjects, entities.keys)
end

rules.all? do |name, rule|
entity = entities[name.to_sym]
Expand All @@ -34,4 +37,12 @@ def valid_for?(entities)
end
end
end

def enabled_for?(subjects = {})
valid_for?(subjects)
end

def disabled_for?(subjects = {})
!valid_for?(subjects)
end
end
36 changes: 0 additions & 36 deletions spec/toggles/feature/base_spec.rb

This file was deleted.

2 changes: 1 addition & 1 deletion spec/toggles/feature/permissions_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
describe Feature::Permissions do
let(:path) { "features/multiple_subjects.yml" }

subject { Feature::Permissions.new(path) }
subject { Feature::Permissions.from_yaml(path) }

its(:rules) { is_expected.to eq({"user"=>{"id"=>1, "logged_in?"=>true},
"widget"=>{"id"=>2}}) }
Expand Down
37 changes: 37 additions & 0 deletions spec/toggles/feature_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
describe 'features' do
let(:user) { double(id: 1, logged_in?: true) }
let(:widget) { double(id: 2) }

context 'multiple subjects' do
specify { expect(Feature).to be_enabled(:multiple_subjects, user: user, widget: widget) }
specify { expect(Feature::MultipleSubjects).to be_enabled_for(user: user, widget: widget) }
specify { expect(Feature).not_to be_disabled(:multiple_subjects, user: user, widget: widget) }
specify { expect(Feature::MultipleSubjects).not_to be_disabled_for(user: user, widget: widget) }
end

context 'abbreviation with numbers' do
subject { Feature::AbbreviationsCN22.new(user: user) }

specify { expect(Feature).to be_enabled(:abbreviations_cn22, user: user) }
specify { expect(Feature::AbbreviationsCN22).to be_enabled_for(user: user) }
specify { expect(Feature).not_to be_disabled(:abbreviations_cn22, user: user) }
specify { expect(Feature::AbbreviationsCN22).not_to be_disabled_for(user: user) }
end

context 'irregular capitalization' do
specify { expect(Feature).to be_enabled(:s3_file, user: user) }
specify { expect(Feature::S3File).to be_enabled_for(user: user) }
specify { expect(Feature).not_to be_disabled(:s3_file, user: user) }
specify { expect(Feature).to be_disabled(:s3_file, user: widget) }
specify { expect(Feature::S3File).not_to be_disabled_for(user: user) }
specify { expect(Feature::S3File).to be_disabled_for(user: widget) }
end

context 'irregular capitalization' do
specify { expect(Feature).to be_enabled(:file_s3, user: user) }
specify { expect(Feature::FileS3).to be_enabled_for(user: user) }
specify { expect(Feature).not_to be_disabled(:file_s3, user: user) }
specify { expect(Feature::FileS3).not_to be_disabled_for(user: user) }
specify { expect(Feature).to be_disabled(:file_s3, user: widget) }
end
end