package WWW::ManageWP::Tests;
use strict;
use warnings;
use Test::More;

##########
## Init ##
##########

BEGIN{
	use_ok('WWW::ManageWP');
	use_ok('WWW::ManageWP::Remote');
	use_ok('WWW::ManageWP::Simple');
}

sub new {
	my $class = shift;
	return bless({}, $class);
}

##########
## Core ##
##########

sub run_all {
	my $class = shift;
	$class->base_load();
	$class->base_methods();
	$class->remote_load();
	$class->remote_methods();
}

################
## Base Tests ##
################

sub base_load {
	eval{WWW::ManageWP->new()};
	is(
		$@,
		"[apiKEY] is a required parameter\n",
		'trying to make a new object without credentials fails',
	);
	undef($@);
	my ($testkey, $testurl) = qw(
		foobarbazbarfoobarbazbar123
		http://localhost/testapi/
	);
	my $managewp = WWW::ManageWP->new(
		apiKEY => $testkey,
		apiURL => $testurl,
	);
	isa_ok($managewp, 'WWW::ManageWP');
}

sub base_methods {
	my ($testkey, $testurl) = qw(
		foobarbazbarfoobarbazbar123
		http://localhost/testapi/
	);
	my $managewp = WWW::ManageWP->new(
		apiKEY => $testkey,
		apiURL => $testurl,
	);
	isa_ok($managewp, 'WWW::ManageWP');
	is($managewp->apiKEY, $testkey, returned_expected('apiKEY'));
	is($managewp->apiURL, $testurl, returned_expected('apiURL'));
}

##################
## Remote Tests ##
##################

sub remote_load {
	eval{WWW::ManageWP::Remote->new()};
	is(
		$@,
		"[apiKEY] is a required parameter\n",
		'trying to make a new object without credentials fails',
	);
	undef($@);
}

sub remote_methods {
	my ($testkey, $testurl) = qw(
		foobarbazbarfoobarbazbar123
		http://localhost/testapi/
	);
	my $remote = WWW::ManageWP::Remote->new(
		apiKEY => $testkey,
		apiURL => $testurl,
	);
	isa_ok($remote, 'WWW::ManageWP::Remote');
	eval{$remote->get};
	is(
		$@,
		"[method] is a required parameter\n",
		failed_expected('get'),
	);
	mock('HTTP::Tiny::get', sub {
		return {
			success => 1,
			status  => 200,
			content => '{"testinfo":"1","status":"0"}',
		}
	});
	mock('HTTP::Tiny::delete', sub {
		return {
			success => 1,
			status  => 200,
			content => '{"testinfo":"1","status":"0"}',
		}
	});
	mock('HTTP::Tiny::post_form', sub {
		return {
			success => 1,
			status  => 200,
			content => '{"testinfo":"1","status":"0"}',
		}
	});
	my $res;
	$res = $remote->delete(
		request_params => {
			test_param1 => 1,
			test_param2 => 0,
		},
		method => 'users/remove',
	);
	ok($res->{testinfo}, returned_expected('delete'));
	$res = $remote->get(
		request_params => {
			test_param1 => 1,
			test_param2 => 0,
		},
		method => 'users/list',
	);
	ok($res->{testinfo}, returned_expected('get'));
	$res = $remote->post(
		request_params => {
			test_param1 => 1,
			test_param2 => 0,
		},
		method => 'users/register',
	);
	ok($res->{testinfo}, returned_expected('post'));
	isa_ok($remote->http, 'HTTP::Tiny');
	isa_ok($remote->json, 'JSON');
	# private method tests
	my $get_params = {
		email => 'test@localhost.com',
		name  => '!@#$%^&*()_+',
	};
	my $built_get_params = $remote->_build_get_params($get_params);
	my @built_get_params = sort(split('&', $built_get_params));
	shift(@built_get_params);
	is(
		$built_get_params[0],
		'email=test%40localhost.com',
		returned_expected('_build_get_params'),
	);
	is(
		$built_get_params[1],
		'name=%21%40%23%24%25%5E%26%2A%28%29_%2B',
		returned_expected('_build_get_params'),
	);
	is(
		$remote->_build_url(method => 'partner/users/list'),
		'http://localhost/testapi/partner/users/list?api_key=foobarbazbarfoobarbazbar123',
		returned_expected('_build_url'),
	);
}

##########
## Help ##
##########

sub returned_expected {
	my $method = shift;
	return "[$method] returned expected results";
}

sub failed_expected {
	my $method = shift;
	return "[$method] failed in an expected manner";
}

#############
## Mocking ##
#############

sub mock {
	my $method = shift;
	my $code   = shift;
	{
		no strict 'refs';
		no warnings 'redefine';
		*{$method} = $code;
	}
	return 1;
}

1;

__END__

=head1 NAME

WWW::ManageWP::Tests

=head1 DESCRIPTION

Tests for WWW::ManageWP and sub-modules

=cut

