-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the possibility to fetch all features already released to a given resource #67
Conversation
This method is reponsible to fetch all related features from a given resource.
expect(storage.all_values(key).sort).to eq values.sort | ||
it 'returns all resource_ids for the given feature_key' do | ||
redis.sadd(feature_key, resource_ids) | ||
expect(storage.all_values(feature_key).sort).to eq resource_ids.sort |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
match_array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
it { expect(storage).to have_value(key, value) } | ||
describe '#has_values?' do | ||
context 'resource_id is stored for given feature_key' do | ||
before { redis.sadd(feature_key, resource_id) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could use the storage.add
method, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sense, done!
it { expect(storage).not_to have_value(key, value) } | ||
context 'when there is features under global structure' do | ||
before do | ||
storage.add(feature_key, resource_name, resource_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the test doesn't need this setup :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
storage.add(feature_key, resource_name, resource_id) | ||
|
||
expect(redis.sismember(feature_key, resource_id)).to be_truthy | ||
expect(redis.sismember(resource_key, feature_key)).to be_truthy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use the redis to make the assertion? And why there are two assertions and only one context?
storage.add_all(global_key, resource_id) | ||
expect(redis.sismember(global_key, resource_id)).to be_truthy | ||
|
||
expect(redis.sismember(feature_key, resource_id)).to be_falsey |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be discussed/done in another PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO it's fine as it is. The single expectation tip is not well accepted by the community and will probably be removed from the guide.
betterspecs/betterspecs#5
https://stackoverflow.com/questions/38437162/whats-the-difference-between-rspecs-subject-and-let-when-should-they-be-used/38459039#38459039
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides, the expects
are co-dependent, we don't want to isolate then, in order the expect from line 71 be valid, it needs to expect
from line 69 to pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I think this can be discussed in another issue, or PR. not related to this change, as long this is actually an opinionated style.
spec/feature_flagger/control_spec.rb
Outdated
@@ -19,19 +20,19 @@ module FeatureFlagger | |||
it { expect(result).to be_falsey } | |||
|
|||
context 'and a feature is release to all' do | |||
before { storage.add(FeatureFlagger::Control::RELEASED_FEATURES, key) } | |||
before { storage.add(FeatureFlagger::Control::RELEASED_FEATURES, resource_name, key) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be using control.release
in all control tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sense, done
it { expect(result).to be_falsey } | ||
end | ||
|
||
context 'when feature was released to all' do | ||
before { storage.add(FeatureFlagger::Control::RELEASED_FEATURES, key) } | ||
before { storage.add_all(FeatureFlagger::Control::RELEASED_FEATURES, key) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
control.release_to_all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right, tests are better now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you missed this one :) It still using storage, IMHO this spec we should not use the storage
class at all only the public API of FeatureFlagger::Control
does that make sense to you? I think we can do this refactor in another time anyways :D
before { redis.sadd(key, value) } | ||
it { expect(storage).to have_value(key, value) } | ||
describe '#has_values?' do | ||
context 'resource_id is stored for given feature_key' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Cleanup features when add_all and remove_all to prevent invalid objects on redis
end | ||
|
||
context 'when add_all is called right after add' do | ||
it 'adds resource_id to redis global key, and clear both resource_id and feature_key' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think a and here means this is two separate contexts?
it { expect(result).to be_falsey } | ||
end | ||
|
||
context 'when feature was released to all' do | ||
before { storage.add(FeatureFlagger::Control::RELEASED_FEATURES, key) } | ||
before { storage.add_all(FeatureFlagger::Control::RELEASED_FEATURES, key) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you missed this one :) It still using storage, IMHO this spec we should not use the storage
class at all only the public API of FeatureFlagger::Control
does that make sense to you? I think we can do this refactor in another time anyways :D
@@ -2,7 +2,7 @@ module FeatureFlagger | |||
class Manager | |||
|
|||
def self.detached_feature_keys | |||
persisted_features = FeatureFlagger.control.search_keys("*").to_a | |||
persisted_features = FeatureFlagger.control.feature_keys |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
lib/feature_flagger/control.rb
Outdated
@@ -13,15 +13,27 @@ def released?(feature_key, resource_id) | |||
end | |||
|
|||
def release(feature_key, resource_id) | |||
@storage.add(feature_key, resource_id) | |||
resource_name = FeatureFlagger::Storage::RedisKeys.extract_resource_name_from_feature_key( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should calls made to RedisKeys
only be made inside the Redis Storage adapter?
Or is it something we would be able to re-use to other types of storages? In that case, I think we should rename RedisKeys to something else.
Why? Keys class it's responsible for decomposing the feature_key and this logic will be needed in others Storages as well. So we are renaming it to make clear it doesn't depends on Redis.
Code Climate has analyzed commit 1eb46df and detected 0 issues on this pull request. The test coverage on the diff in this pull request is 100.0% (80% is the threshold). This pull request will bring the total coverage in the repository to 99.0% (0.2% change). View more on Code Climate. |
This PR introduces the ability to fetch which features were released to a given resource (account, user, etc).