Commit 56bb5374 authored by Ash McKenzie's avatar Ash McKenzie

New FlipperSession and FlipperSessionHelper

FlipperSession is designed to be used with
Feature (and Flipper) to allow A/B style testing
for anonymous users.

FlipperSessionHelper leverages FlipperSession.
parent 6f9ee533
# frozen_string_literal: true
module EE
module FlipperSessionHelper
def flipper_session
@flipper_session ||= flipper_session_set? ? get_flipper_session : new_flipper_session
end
private
def flipper_session_set?
session.has_key?(FlipperSession::SESSION_KEY)
end
def get_flipper_session
FlipperSession.new(session[FlipperSession::SESSION_KEY])
end
def new_flipper_session
FlipperSession.new.tap do |flipper_session|
session[FlipperSession::SESSION_KEY] = flipper_session.id
end
end
end
end
---
title: Use Flipper as an A/B testing framework
merge_request: 13755
author:
type: added
# frozen_string_literal: true
require 'securerandom'
class FlipperSession
SESSION_KEY = '_flipper_id'.freeze
attr_reader :id
def initialize(id = generate_id)
@id = id
end
# This method is required by Flipper
# https://github.com/jnunemaker/flipper/blob/master/docs/Gates.md#2-individual-actor
def flipper_id
"flipper_session:#{id}"
end
private
def generate_id
SecureRandom.uuid
end
end
# frozen_string_literal: true
require 'spec_helper'
describe EE::FlipperSessionHelper do
describe '.flipper_session' do
let(:session) { {} }
before do
allow(helper).to receive(:session).and_return(session)
end
subject { helper.flipper_session }
context 'when a FlipperSession has not be previously set' do
let(:predictable_id) { 'abc123' }
before do
allow_any_instance_of(FlipperSession).to receive(:generate_id).and_return(predictable_id)
end
it 'returns an instance of FlipperSession' do
expect(subject).to be_instance_of(FlipperSession)
end
it 'sets a predictable FlipperSession id to session' do
subject
expect(session).to include(FlipperSession::SESSION_KEY => predictable_id)
end
end
context 'when a FlipperSession has been previously set' do
let(:predictable_id) { 'def456' }
before do
allow_any_instance_of(FlipperSession).to receive(:generate_id).and_return(predictable_id)
end
it 'returns a FlipperSession with the same ID' do
# Cannot call subject as it will be cached and not trigger the logic a second time
existing_flipper_session = helper.flipper_session
expect(subject.id).to eq(existing_flipper_session.id)
end
end
end
end
# frozen_string_literal: true
require 'fast_spec_helper'
describe FlipperSession do
describe '#flipper_id' do
context 'without passing in an ID' do
it 'returns a flipper_session:UUID' do
expect(described_class.new.flipper_id).to match(/\Aflipper_session:\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\z/)
end
end
context 'passing in an ID' do
it 'returns a flipper_session:def456' do
id = 'abc123'
expect(described_class.new(id).flipper_id).to eq("flipper_session:#{id}")
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment