view release on metacpan or search on metacpan
received the program in object code or executable form alone.)
Source code for a work means the preferred form of the work for making
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
7. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of the license which applies to it and "any
may not charge a fee for this Package itself. However, you may distribute this
Package in aggregate with other (possibly commercial) programs as part of a
larger (possibly commercial) software distribution provided that you do not
advertise this Package as a product of your own.
6. The scripts and library files supplied as input to or produced as output
from the programs of this Package do not automatically fall under the copyright
of this Package, but belong to whomever generated them, and may be sold
commercially, and may be aggregated with this Package.
7. C or perl subroutines supplied by you and linked into this Package shall not
be considered part of this Package.
8. The name of the Copyright Holder may not be used to endorse or promote
products derived from this software without specific prior written permission.
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
lib/API/Instagram.pm view on Meta::CPAN
use API::Instagram::User;
use API::Instagram::Location;
use API::Instagram::Tag;
use API::Instagram::Media;
use API::Instagram::Media::Comment;
use API::Instagram::Search;
has client_id => ( is => 'ro', required => 1 );
has client_secret => ( is => 'ro', required => 1 );
has redirect_uri => ( is => 'ro', required => 1 );
has scope => ( is => 'ro', default => sub { 'basic' } );
has response_type => ( is => 'ro', default => sub { 'code' } );
has grant_type => ( is => 'ro', default => sub { 'authorization_code' } );
has code => ( is => 'rw', isa => sub { confess "Code not provided" unless $_[0] } );
has access_token => ( is => 'rw', isa => sub { confess "No access token provided" unless $_[0] } );
has no_cache => ( is => 'rw', default => sub { 0 } );
has _ua => ( is => 'ro', default => sub { Furl->new() } );
has _obj_cache => ( is => 'ro', default => sub { { User => {}, Media => {}, Location => {}, Tag => {}, 'Media::Comment' => {} } } );
has _endpoint_url => ( is => 'ro', default => sub { 'https://api.instagram.com/v1' } );
has _authorize_url => ( is => 'ro', default => sub { 'https://api.instagram.com/oauth/authorize' } );
has _access_token_url => ( is => 'ro', default => sub { 'https://api.instagram.com/oauth/access_token' } );
has _debug => ( is => 'rw', lazy => 1 );
my $instance;
sub BUILD { $instance = shift }
sub instance { $instance //= shift->new(@_) }
sub get_auth_url {
my $self = shift;
carp "User already authorized with code: " . $self->code if $self->code;
my @auth_fields = qw(client_id redirect_uri response_type scope);
for ( @auth_fields ) {
carp "ERROR: $_ required for generating authorization URL" and return unless defined $self->$_;
}
my $uri = URI->new( $self->_authorize_url );
$uri->query_form( map { $_ => $self->$_ } @auth_fields );
$uri->as_string();
}
sub get_access_token {
my $self = shift;
my @access_token_fields = qw(client_id redirect_uri grant_type client_secret code);
for ( @access_token_fields ) {
carp "ERROR: $_ required for generating access token." and return unless defined $self->$_;
}
my $data = { map { $_ => $self->$_ } @access_token_fields };
my $json = $self->_request( 'post', $self->_access_token_url, $data, { token_not_required => 1 } );
wantarray ? ( $json->{access_token}, $self->user( $json->{user} ) ) : $json->{access_token};
}
sub media { shift->_get_obj( 'Media', 'id', shift ) }
sub user { shift->_get_obj( 'User', 'id', shift // 'self' ) }
sub location { shift->_get_obj( 'Location', 'id', shift, 1 ) }
sub tag { shift->_get_obj( 'Tag', 'name', shift ) }
sub search {
my $self = shift;
my $type = shift;
API::Instagram::Search->new( type => $type )
}
sub popular_medias {
my $self = shift;
my $url = "/media/popular";
$self->_medias( $url, { @_%2?():@_ } );
}
sub _comment { shift->_get_obj( 'Media::Comment', 'id', shift ) }
#####################################################
# Returns cached wanted object or creates a new one #
#####################################################
sub _get_obj {
my ( $self, $type, $key, $code, $optional_code ) = @_;
my $data = { $key => $code };
$data = $code if ref $code eq 'HASH';
$code = $data->{$key};
# Returns if CODE is not optional and not defined or if it's not a string
return if (!$optional_code and !defined $code) or ref $code;
# Code used as cache key
lib/API/Instagram.pm view on Meta::CPAN
# Deletes cache if no-cache is set
delete $self->_cache($type)->{$cache_code} if $self->no_cache;
return $return;
}
###################################
# Returns a list of Media Objects #
###################################
sub _medias {
my ($self, $url, $params, $opts) = @_;
$params->{count} //= 33;
$params->{url} = $url;
[ map { $self->media($_) } $self->_get_list( { %$params, url => $url }, $opts ) ]
}
####################################################################
# Returns a list of the requested items. Does pagination if needed #
####################################################################
sub _get_list {
my $self = shift;
my $params = shift;
my $opts = shift;
my $url = delete $params->{url} || return [];
my $count = $params->{count} // 999_999_999;
$count = 999_999_999 if $count < 0;
$params->{count} = $count;
my $request = $self->_request( 'get', $url, $params, $opts );
lib/API/Instagram.pm view on Meta::CPAN
$request = $self->_request( 'get', $pagination->{next_url}, $params, $opts );
push @$data, @{ $request->{data} };
}
return @$data;
}
##############################################################
# Requests the data from the given URL with QUERY parameters #
##############################################################
sub _request {
my ( $self, $method, $url, $params, $opts ) = @_;
# Verifies access requirements
unless ( defined $self->access_token ) {
if ( !$opts->{token_not_required} or !defined $self->client_id ) {
carp "A valid access_token is required";
return {}
}
}
lib/API/Instagram.pm view on Meta::CPAN
# Verifies meta node
my $meta = $res->{meta};
carp "$meta->{error_type}: $meta->{error_message}" if $meta->{code} ne '200';
use Data::Dumper;
# die Dumper $res;
$res;
}
sub _request_data { shift->_request(@_)->{data} || {} }
sub _del { shift->_request_data( 'delete', @_ ) }
sub _get { shift->_request_data( 'get', @_ ) }
sub _post { shift->_request_data( 'post', @_ ) }
################################
# Returns requested cache hash #
################################
sub _cache { shift->_obj_cache->{ shift() } }
1;
__END__
=pod
=encoding UTF-8
lib/API/Instagram/Location.pm view on Meta::CPAN
use Moo;
use Carp;
has id => ( is => 'ro', predicate => 1 );
has latitude => ( is => 'lazy' );
has longitude => ( is => 'lazy' );
has name => ( is => 'lazy' );
has _data => ( is => 'rwp', lazy => 1, builder => 1, clearer => 1 );
sub recent_medias {
my $self = shift;
carp "Not available for location with no ID." and return [] unless $self->has_id;
my $url = sprintf "locations/%s/media/recent", $self->id;
API::Instagram->instance->_medias( $url, { @_%2?():@_ } );
}
sub _build_name { shift->_data->{name} }
sub _build_latitude { shift->_data->{latitude} }
sub _build_longitude { shift->_data->{longitude} }
sub _build__data {
my $self = shift;
carp "Not available for location with no ID." and return {} unless $self->has_id;
my $url = sprintf "locations/%s", $self->id;
API::Instagram->instance->_get( $url );
}
1;
__END__
lib/API/Instagram/Media.pm view on Meta::CPAN
has id => ( is => 'ro', required => 1 );
has type => ( is => 'lazy' );
has link => ( is => 'lazy' );
has filter => ( is => 'lazy' );
has images => ( is => 'lazy' );
has videos => ( is => 'lazy' );
has user => ( is => 'lazy', coerce => \&_coerce_user );
has tags => ( is => 'lazy', coerce => \&_coerce_tags );
has location => ( is => 'lazy', coerce => \&_coerce_location );
has users_in_photo => ( is => 'lazy', coerce => \&_coerce_users_in_photo );
has caption => ( is => 'lazy', coerce => sub { $_[0]->{text} if $_[0] and ref $_[0] eq 'HASH' } );
has created_time => ( is => 'lazy', coerce => sub { Time::Moment->from_epoch( $_[0] ) } );
has _api => ( is => 'lazy' );
has _data => ( is => 'rwp', lazy => 1, builder => 1, clearer => 1 );
sub likes {
my $self = shift;
$self->_clear_data if shift;
$self->_data->{likes}->{count}
}
sub last_likes {
my $self = shift;
$self->_clear_data if shift;
my $api = $self->_api;
[ map { $api->user($_) } @{ $self->_data->{likes}->{data} } ]
}
sub get_likes {
my $self = shift;
my %opts = @_;
my $url = sprintf "media/%s/likes", $self->id;
my $api = $self->_api;
[ map { $api->user($_) } $api->_get_list( { %opts, url => $url } ) ]
}
sub like {
my $self = shift;
my $url = sprintf "media/%s/likes", $self->id;
$self->_api->_post( $url )
}
sub dislike {
my $self = shift;
my $url = sprintf "media/%s/likes", $self->id;
$self->_api->_del( $url )
}
sub comments {
my $self = shift;
$self->_clear_data if shift;
$self->_data->{comments}->{count}
}
sub last_comments {
my $self = shift;
$self->_clear_data if shift;
my $api = $self->_api;
[ map { $api->_comment( { %$_, media => $self } ) } @{ $self->_data->{comments}->{data} } ]
}
sub get_comments {
my $self = shift;
my %opts = @_;
my $url = sprintf "media/%s/comments", $self->id;
my $api = $self->_api;
[ map { $api->_comment( { %$_, media => $self } ) } $api->_get_list( { %opts, url => $url } ) ]
}
sub comment {
my $self = shift;
my $text = shift;
my $url = sprintf "media/%s/comments", $self->id;
$self->_api->_post( $url, { text => $text } )
}
sub _build__api { API::Instagram->instance }
sub _build_user { shift->_data->{user} }
sub _build_tags { shift->_data->{tags} }
sub _build_location { shift->_data->{location} }
sub _build_users_in_photo { shift->_data->{users_in_photo} }
sub _build_type { shift->_data->{type} }
sub _build_link { shift->_data->{link} }
sub _build_filter { shift->_data->{filter} }
sub _build_images { shift->_data->{images} }
sub _build_videos { shift->_data->{videos} }
sub _build_caption { shift->_data->{caption } }
sub _build_created_time { shift->_data->{created_time} }
sub _build__data {
my $self = shift;
my $url = sprintf "media/%s", $self->id;
$self->_api->_get( $url );
}
############################################################
# Attributes coercion that API::Instagram object reference #
############################################################
sub _coerce_user { API::Instagram->instance->user ( $_[0] ) };
sub _coerce_location { API::Instagram->instance->location( $_[0] ) if $_[0] };
sub _coerce_tags {
my $data = $_[0];
return if ref $data ne 'ARRAY';
[ map { API::Instagram->instance->tag($_) } @$data ]
};
sub _coerce_users_in_photo {
my $data = $_[0];
return if ref $data ne 'ARRAY';
[
map {{
user => API::Instagram->instance->user( $_->{user} ),
position => $_->{position},
}} @$data
]
};
lib/API/Instagram/Media/Comment.pm view on Meta::CPAN
package API::Instagram::Media::Comment;
# ABSTRACT: Instagram Media Comment Object
use Moo;
use Time::Moment;
has id => ( is => 'ro', required => 1 );
has from => ( is => 'ro', required => 1, coerce => sub { API::Instagram->instance->user( $_[0] ) } );
has text => ( is => 'ro', required => 1 );
has media => ( is => 'ro', required => 1 );
has created_time => ( is => 'ro', coerce => sub { Time::Moment->from_epoch( $_[0] ) } );
sub remove {
my $self = shift;
my $url = sprintf "media/%s/comments/%s", $self->media->id, $self->id;
$self->media->_api->_del( $url )
}
1;
__END__
=pod
lib/API/Instagram/Search.pm view on Meta::CPAN
use Moo;
my $search = {
user => 'users/search',
media => 'media/search',
tag => 'tags/search',
location => 'locations/search',
};
has type => ( is => 'ro', required => 1, isa => sub { die "Type not supported." unless $search->{$_[0]} } );
sub find {
my $self = shift;
my %opts = @_;
my $type = $self->type;
my $url = $search->{$type};
my $api = API::Instagram->instance;
[ map { $api->$type($_) } $api->_get_list( { %opts, url => $url } ) ]
}
1;
lib/API/Instagram/Tag.pm view on Meta::CPAN
package API::Instagram::Tag;
# ABSTRACT: Instagram Tag Object
use Moo;
has name => ( is => 'ro', required => 1 );
has _data => ( is => 'rwp', lazy => 1, builder => 1, clearer => 1 );
sub media_count {
my $self = shift;
$self->_clear_data if shift;
$self->_data->{media_count}
}
sub recent_medias {
my $self = shift;
my $url = sprintf "tags/%s/media/recent", $self->name;
API::Instagram->instance->_medias( $url, { @_%2?():@_ } );
}
sub _build__data {
my $self = shift;
my $url = sprintf "tags/%s", $self->name;
API::Instagram->instance->_get( $url );
}
1;
__END__
=pod
lib/API/Instagram/User.pm view on Meta::CPAN
has id => ( is => 'ro', required => 1 );
has username => ( is => 'lazy' );
has full_name => ( is => 'lazy' );
has bio => ( is => 'lazy' );
has website => ( is => 'lazy' );
has profile_picture => ( is => 'lazy' );
has _api => ( is => 'lazy' );
has _data => ( is => 'rwp', lazy => 1, builder => 1, clearer => 1 );
sub media {
my $self = shift;
$self->_clear_data if shift;
return $_->{media} for $self->_data->{counts}
}
sub follows {
my $self = shift;
$self->_clear_data if shift;
return $_->{follows} for $self->_data->{counts}
}
sub followed_by {
my $self = shift;
$self->_clear_data if shift;
return $_->{followed_by} for $self->_data->{counts}
}
sub feed {
my $self = shift;
my @list = $self->_self_requests( 'feed', '/users/self/feed', @_ ) or return;
[ map { $self->_api->media($_) } @list ];
}
sub liked_media {
my $self = shift;
my @list = $self->_self_requests( 'liked-media', '/users/self/media/liked', @_ ) or return;
[ map { $self->_api->media($_) } @list ];
}
sub requested_by {
my $self = shift;
my @list = $self->_self_requests( 'requested-by', '/users/self/requested-by', @_ ) or return;
[ map { $self->_api->user($_) } @list ];
}
sub get_follows {
shift->_get_relashions( @_, relationship => 'follows' );
}
sub get_followers {
shift->_get_relashions( @_, relationship => 'followed-by' );
}
sub recent_medias {
my $self = shift;
my $url = sprintf "users/%s/media/recent", $self->id;
$self->_api->_medias( $url, { @_%2?():@_ }, { token_not_required => 1 } );
}
sub relationship {
my $self = shift;
my $action = shift;
my $url = sprintf "users/%s/relationship", $self->id;
my @actions = qw/ follow unfollow block unblock approve ignore/;
use experimental 'smartmatch';
if ( $action ) {
if ( $action ~~ @actions ){
return $self->_api->_post( $url, { action => $action } )
}
carp "Invalid action";
}
$self->_api->_get( $url );
}
sub _get_relashions {
my $self = shift;
my %opts = @_;
my $url = sprintf "users/%s/%s", $self->id, $opts{relationship};
my $api = $self->_api;
[ map { $api->user($_) } $api->_get_list( { %opts, url => $url } ) ]
}
sub _self_requests {
my ($self, $type, $url, %opts) = @_;
if ( $self->id ne $self->_api->user->id ){
carp "The $type is only available for the authenticated user";
return;
}
$self->_api->_get_list( { %opts, url => $url } )
}
sub BUILDARGS {
my $self = shift;
my $opts = shift;
$opts->{profile_picture} //= delete $opts->{profile_pic_url} if exists $opts->{profile_pic_url};
return $opts;
}
sub _build__api { API::Instagram->instance }
sub _build_username { shift->_data->{username} }
sub _build_full_name { shift->_data->{full_name} }
sub _build_bio { shift->_data->{bio} }
sub _build_website { shift->_data->{website} }
sub _build_profile_picture { shift->_data->{profile_picture} }
sub _build__data {
my $self = shift;
my $url = sprintf "users/%s", $self->id;
$self->_api->_get( $url );
}
1;
__END__
t/00-comment.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1,
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
my $media = $api->media(123);
isa_ok( $media, 'API::Instagram::Media' );
my $get_comments = $media->get_comments;
is ref $get_comments, 'ARRAY';
my $comment = $get_comments->[0];
isa_ok( $comment, 'API::Instagram::Media::Comment' );
t/00-instagram.t view on Meta::CPAN
use Furl::Response;
use Inline::Files;
use API::Instagram;
use Test::More tests => 17;
my $data = join '', <DATA>;
my $ua = Test::MockObject::Extends->new( Furl->new() );
my $res = Test::MockObject::Extends->new( Furl::Response->new( 1, 200, 'OK', {}, $data) );
$ua->mock('get', sub { $res });
$ua->mock('post', sub { $res });
my $api = API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1,
_ua => $ua,
});
t/00-instagram.t view on Meta::CPAN
is $me->username, "snoopdogg";
is ref $api->_request('get','media'), 'HASH';
my @list = $api->_get_list( { url => 'media', count => 2 } );
is ~~@list , 2;
# Tests Popular Medias method with new DATA (__POPULAR__)
my $popular = join '', <POPULAR>;
my $res2 = Test::MockObject::Extends->new( Furl::Response->new( 1, 200, 'OK', {}, $popular) );
$ua->mock('get', sub { $res2 });
is ref $api2->popular_medias, 'ARRAY';
is $api2->popular_medias->[0]->user->username, 'cocomiin';
__DATA__
{
"meta": {
"code": 200
},
"pagination": {
t/00-location.t view on Meta::CPAN
my $api = Test::MockObject::Extends->new(
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $location = $api->location('1');
isa_ok( $location, 'API::Instagram::Location' );
is $location->id, 1;
is $location->name, 'Dogpatch Labs';
is $location->latitude, 37.782;
is $location->longitude, -122.387;
is ref $location->recent_medias, 'ARRAY';
t/00-media.t view on Meta::CPAN
use API::Instagram;
use Test::More tests => 27;
my $api = Test::MockObject::Extends->new(
API::Instagram->new({
client_id => '123', client_secret => '456', redirect_uri => 'http://localhost', no_cache => 1, })
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { {} });
# First Object
my $media = $api->media(3);
isa_ok( $media, 'API::Instagram::Media' );
is $media->id, 3;
is $media->type, 'video';
is $media->filter, 'Vesper';
is $media->likes, 1;
is $media->comments, 2;
t/00-search.t view on Meta::CPAN
my $api = Test::MockObject::Extends->new(
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
my $search = $api->search('tag');
isa_ok( $search, 'API::Instagram::Search' );
my $tags = $search->find( q => 'x' );
is ref $tags, 'ARRAY';
isa_ok( $tags->[0], 'API::Instagram::Tag' );
is $tags->[3]->name, 'snowydays';
my $api = Test::MockObject::Extends->new(
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $tag = $api->tag('nofilter');
isa_ok( $tag, 'API::Instagram::Tag' );
is $tag->name, 'nofilter';
is $tag->media_count, 472;
is $tag->media_count(1), 472;
is ref $tag->recent_medias, 'ARRAY';
__DATA__
t/00-user.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $user = $api->user("1574083");
isa_ok( $user, 'API::Instagram::User' );
is $user->id, 1574083;
is $user->username, 'snoopdogg';
is $user->full_name, 'Snoop Dogg';
is $user->bio, 'This is my bio';
is $user->website, 'http://snoopdogg.com';
is $user->profile_picture, 'http://distillery.s3.amazonaws.com/profiles/profile_1574083_75sq_1295469061.jpg';
t/01-location.t view on Meta::CPAN
my $api = Test::MockObject::Extends->new(
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $location = $api->location( $json->{data} );
isa_ok( $location, 'API::Instagram::Location' );
is $location->id, undef;
is $location->name, undef;
is ref $location->recent_medias, 'ARRAY';
__DATA__
{
t/01-media.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1,
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $media = $api->media( $json->{data} );
isa_ok( $media, 'API::Instagram::Media' );
is $media->location, undef;
is ref $media->tags, 'ARRAY';
is $media->tags->[0], undef;
my $uip = $media->users_in_photo;
is ref $uip, 'ARRAY';
t/01-search.t view on Meta::CPAN
my $api = Test::MockObject::Extends->new(
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
my $search = eval { $api->search('car') };
is $search, undef;
__DATA__
{
"data": [
{
"media_count": 43590,
"name": "snowy"
t/01-user.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $user = $api->user( $json->{data} );
isa_ok( $user, 'API::Instagram::User' );
is $user->id, 'self';
is $user->profile_picture, 'http://distillery.s3.amazonaws.com/profiles/profile_1574083_75sq_1295469061.jpg';
is ref $user->feed, 'ARRAY';
is ref $user->liked_media, 'ARRAY';
is ref $user->requested_by, 'ARRAY';
t/02-user.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $user = $api->user( $json->{data} );
isa_ok( $user, 'API::Instagram::User' );
is $user->id, 123;
is $user->profile_picture, 'http://test.com/picture.jpg';
is $user->feed, undef;
is $user->liked_media, undef;
is $user->requested_by, undef;
t/03-user.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_get_list', sub { [] });
my $user = $api->user( $json->{data} );
isa_ok( $user, 'API::Instagram::User' );
is $user->profile_picture, undef;
__DATA__
{
"data": {
"id": "1574083",
t/04-user.t view on Meta::CPAN
API::Instagram->new({
client_id => '123',
client_secret => '456',
redirect_uri => 'http://localhost',
no_cache => 1
})
);
my $data = join '', <DATA>;
my $json = decode_json $data;
$api->mock('_request', sub { $json });
$api->mock('_post', sub { $json });
my $user = $api->user( 123 );
isa_ok( $user, 'API::Instagram::User' );
is ref $user->relationship, 'HASH';
is $user->relationship->{incoming_status}, 'requested_by';
is ref $user->relationship('block'), 'HASH';
is ref $user->relationship('undef'), 'HASH';
__DATA__