File Coverage

blib/lib/WWW/Sixpack.pm
Criterion Covered Total %
statement 32 52 61.5
branch 6 16 37.5
condition 4 11 36.3
subroutine 10 12 83.3
pod 3 3 100.0
total 55 94 58.5


line stmt bran cond sub pod time code
1             package WWW::Sixpack;
2              
3 2     2   28358 use 5.006;
  2         4  
4 2     2   8 use strict;
  2         2  
  2         46  
5 2     2   6 use warnings FATAL => 'all';
  2         6  
  2         71  
6              
7 2     2   7 use Carp qw( croak );
  2         9  
  2         102  
8 2     2   911 use Data::UUID;
  2         1016  
  2         108  
9 2     2   1071 use JSON::Any;
  2         5115  
  2         9  
10 2     2   19216 use LWP::UserAgent;
  2         74953  
  2         68  
11 2     2   17 use URI;
  2         2  
  2         832  
12              
13             our $VALID_NAME_RE = qr/^[a-z0-9][a-z0-9\-_ ]*$/;
14              
15             =head1 NAME
16              
17             WWW::Sixpack - Perl client library for SeatGeek's Sixpack A/B testing framework http://sixpack.seatgeek.com/
18              
19             =cut
20              
21             our $VERSION = '0.04';
22              
23             =head1 SYNOPSIS
24              
25             use WWW::Sixpack;
26              
27             my $sixpack = WWW::Sixpack->new();
28              
29             # Participate in a test (creates the test if necessary)
30             my $alternative = $sixpack->participate('new-test', [ 'alt-1', 'alt-2' ],
31             { ip_address => $client_ip, user_agent => $client_ua,
32             force => 'alt-2', traffic_fraction => 0.10 });
33              
34             if( $alternative->{alternative}{name} eq 'alt-1' ) {
35             # show data for variant alt-1
36             } else {
37             # show data for variant alt-2
38             }
39              
40             # Convert
41             $sixpack->convert('new-test')
42              
43             =head1 SUBROUTINES/METHODS
44              
45             =head2 new
46              
47             Constructs the WWW::Sixpack object. Options that can be passed in are:
48              
49             =over 4
50              
51             =item C
52              
53             The sixpack server (defaults to 'http://localhost:5000').
54              
55             =item C
56              
57             The client id if the "user" is known already. By default we generate a new UUID.
58              
59             =item C
60              
61             The useragent to use (defaults to L).
62              
63             =back
64              
65             =cut
66              
67             sub new {
68 1     1 1 11 my ($class, %args) = @_;
69 1         8 my $self = {
70             host => 'http://localhost:5000',
71             ua => LWP::UserAgent->new,
72             json => JSON::Any->new,
73             client_id => Data::UUID->new->create_str,
74             %args,
75             };
76 1         4005 bless $self, $class;
77             }
78              
79             =head2 participate
80              
81             This function takes the following arguments:
82              
83             Arguments:
84              
85             =over 4
86              
87             =item C
88              
89             The name of the experiment. This will generate a new experiment when the name is unknown.
90              
91             =item C
92              
93             At least two alternatives.
94              
95             =item C
96              
97             An optional hashref with the following options:
98              
99             =over 4
100              
101             =item C
102              
103             User agent of the user making a request. Used for bot detection.
104              
105             =item C
106              
107             IP address of user making a request. Used for bot detection.
108              
109             =item C
110              
111             (optional) Force a specific alternative to be returned
112              
113             =item C
114              
115             (optional) Sixpack allows for limiting experiments to a subset of traffic. You can pass the percentage of traffic you'd like to expose the test to as a decimal number here. (0.10 for 10%)
116              
117             =back
118              
119             =back
120              
121             =cut
122              
123             sub participate {
124 3     3 1 1261 my ($self, $experiment, $alternatives, $options) = @_;
125              
126 3 100       35 croak('Bad experiment name')
127             if( $experiment !~ m/$VALID_NAME_RE/ );
128 2 100 33     29 croak('Must specify at least 2 alternatives')
      33        
      66        
129             if( !$alternatives || !ref $alternatives ||
130             ref $alternatives ne 'ARRAY' || @$alternatives < 2 );
131              
132 1         2 for my $alt (@{$alternatives}) {
  1         2  
133 2 100       15 croak('Bad alternative name: '.$alt) if( $alt !~ m/$VALID_NAME_RE/ );
134             }
135              
136 0   0       $options ||= { };
137              
138             my %params = (
139             client_id => $self->{client_id},
140             experiment => $experiment,
141             alternatives => $alternatives,
142 0           %{$options}
  0            
143             );
144              
145 0           my $res = $self->_get_response('/participate', \%params);
146             $res->{alternative}{name} = $alternatives->[0]
147 0 0         if( $res->{status} eq 'failed' );
148              
149 0           return $res;
150             }
151              
152             =head2 convert
153              
154             This function takes the following arguments:
155              
156             Arguments:
157              
158             =over 4
159              
160             =item C
161              
162             The name of the experiment.
163              
164             =item C
165              
166             A KPI you wish to track. When the KPI is unknown, it will be created.
167              
168             =back
169              
170             =cut
171              
172             sub convert {
173 0     0 1   my ($self, $experiment, $kpi) = @_;
174              
175 0 0         croak('Bad experiment name')
176             if( $experiment !~ m/$VALID_NAME_RE/ );
177              
178             my %params = (
179             client_id => $self->{client_id},
180 0           experiment => $experiment,
181             );
182              
183 0 0         if( $kpi ) {
184 0 0         croak('Bad KPI name')
185             if( $kpi !~ m/$VALID_NAME_RE/ );
186 0           $params{kpi} = $kpi;
187             }
188              
189 0           return $self->_get_response('/convert', \%params);
190              
191             }
192              
193             =head2 _get_response
194              
195             Internal method to fire the actual request and parse the result
196              
197             =cut
198              
199             sub _get_response {
200 0     0     my ($self, $endpoint, $params) = @_;
201              
202 0           my $uri = URI->new($self->{host});
203 0           $uri->path($endpoint);
204 0           $uri->query_form( $params );
205              
206 0           my $resp = $self->{ua}->get( $uri );
207 0 0         my $json = ( $resp->is_success )
208             ? $resp->content
209             : '{"status": "failed", "response": "http error: sixpack is unreachable"}';
210              
211 0           return $self->{json}->jsonToObj( $json );
212             }
213              
214             =head1 AUTHOR
215              
216             Menno Blom, C<< >>
217              
218             =head1 BUGS
219              
220             Please report any bugs or feature requests to C, or through
221             the web interface at L. I will be notified, and then you'll
222             automatically be notified of progress on your bug as I make changes.
223              
224             =head1 SUPPORT
225              
226             You can find documentation for this module with the perldoc command.
227              
228             perldoc WWW::Sixpack
229              
230              
231             You can also look for information at:
232              
233             =over 4
234              
235             =item * RT: CPAN's request tracker (report bugs here)
236              
237             L
238              
239             =item * AnnoCPAN: Annotated CPAN documentation
240              
241             L
242              
243             =item * CPAN Ratings
244              
245             L
246              
247             =item * Search CPAN
248              
249             L
250              
251             =back
252              
253             =head1 LICENSE
254              
255             This library is free software; you can redistribute it and/or modify
256             it under the same terms as Perl itself.
257              
258             =cut
259              
260             1;