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');
}

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

sub run_all {
	my $class = shift;
	foreach my $request (qw/get delete post_form/) {
		mock("HTTP::Tiny::$request", sub {
			return {
				success => 1,
				status  => 200,
				content => '{"message":"1","status":"0"}',
			}
		});
	}
	$class->base();
	$class->remote();
	$class->simple();
}

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

sub base {
	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');
	isa_ok($managewp->remote, 'WWW::ManageWP::Remote');
	isa_ok($managewp->simple, 'WWW::ManageWP::Simple');
	is($managewp->apiKEY, $testkey, returned_expected('apiKEY'));
	is($managewp->apiURL, $testurl, returned_expected('apiURL'));
	# autoload
	eval {$managewp->foobar};
	is($@, "ERROR! [foobar] is not a valid method\n", returned_expected('AUTOLOAD'));
	undef($@);
	# private methods
	eval {$managewp->_prep_args(['foo', 'bar'], {})};
	is($@, "[foo] is a required parameter\n", returned_expected('_prep_args'));
	my %hash    = (foo => 1, bar => 1);
	my $hashref = $managewp->_prep_args([], %hash);
	is ($hash{foo}, $hashref->{foo}, returned_expected('_prep_args'));
	is ($hash{bar}, $hashref->{bar}, returned_expected('_prep_args'));

}

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

sub remote {
	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'),
	);
	my $res;
	$res = $remote->delete(
		request_params => {
			test_param1 => 1,
			test_param2 => 0,
		},
		method => 'users/remove',
	);
	ok($res->{message}, returned_expected('delete'));
	$res = $remote->get(
		request_params => {
			test_param1 => 1,
			test_param2 => 0,
		},
		method => 'users/list',
	);
	ok($res->{message}, returned_expected('get'));
	$res = $remote->post(
		request_params => {
			test_param1 => 1,
			test_param2 => 0,
		},
		method => 'users/register',
	);
	ok($res->{message}, 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'),
	);
}

##################
## Simple Tests ##
##################

sub simple {
	my ($testkey, $testurl) = qw(
		foobarbazbarfoobarbazbar123
		http://localhost/testapi/
	);
	my $simple = WWW::ManageWP::Simple->new(
		apiKEY => $testkey,
		apiURL => $testurl,
	);
	isa_ok($simple, 'WWW::ManageWP::Simple');
	my $users = $simple->list_users();
	ok($users->{message}, returned_expected('list_users'));
	my $register_response = $simple->register_user(user_email => 'test@example.com');
	ok($register_response->{message}, returned_expected('register_user'));
	my $remove_response = $simple->remove_user(user_email => 'test@example.com');
	ok($remove_response->{message}, returned_expected('remove_user'));
	my $autologin_response = $simple->autologin_user(user_email => 'test@example.com');
	ok($autologin_response->{message}, returned_expected('autologin_user'));
	my $changeplan_response = $simple->change_plan(
		user_email => 'test@example.com',
		plan_id    => 'testplan1',
	);
	ok($changeplan_response->{message}, returned_expected('change_plan'));
	# private methods
	eval {$simple->_email_or_die('not an email address')};
	is($@, "ERROR! email address [not an email address}] is not valid\n", returned_expected('_email_or_die'));
}

##########
## 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

