# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.

############################################
# Test for xmlrpc call to Product.create() #
############################################

use 5.14.0;
use strict;
use warnings;

use FindBin qw($RealBin);
use lib "$RealBin/../lib";

use Test::More tests => 121;
use QA::Util;

use constant DESCRIPTION => 'Product created by Product.create';
use constant PROD_VERSION => 'unspecified';

sub post_success {
    my ($call, $test, $self) = @_;
    my $args = $test->{args};
    my $prod_id = $call->result->{id};
    ok($prod_id, "Got a non-zero product ID: $prod_id");

    $call = $self->bz_call_success("Product.get", {ids => [$prod_id]});
    my $product = $call->result->{products}->[0];
    my $prod_name = $product->{name};
    my $is_active = defined $args->{is_open} ? $args->{is_open} : 1;
    ok($product->{is_active} == $is_active,
       "Product $prod_name has the correct value for is_active/is_open: $is_active");
    my $has_unco = defined $args->{has_unconfirmed} ? $args->{has_unconfirmed} : 1;
    ok($product->{has_unconfirmed} == $has_unco,
       "Product $prod_name has the correct value for has_unconfirmed: $has_unco");
}

my ($config, $xmlrpc, $jsonrpc, $jsonrpc_get) = get_rpc_clients();

my @tests = (
    { args  => { name => random_string(20), version => PROD_VERSION,
                 description => DESCRIPTION },
      error => 'You must log in',
      test  => 'Logged-out user cannot call Product.create',
    },
    { user  => 'unprivileged',
      args  => { name => random_string(20), version => PROD_VERSION,
                 description => DESCRIPTION },
      error => 'you are not authorized',
      test  => 'Unprivileged user cannot call Product.create',
    },
    { user  => 'admin',
      args  => { version => PROD_VERSION, description => DESCRIPTION },
      error => 'You must enter a name',
      test  => 'Missing name to Product.create',
    },
    { user  => 'admin',
      args  => { name => random_string(20), version => PROD_VERSION },
      error => 'You must enter a description',
      test  => 'Missing description to Product.create',
    },
    { user  => 'admin',
      args  => { name => random_string(20), description => DESCRIPTION },
      error => 'You must enter a valid version',
      test  => 'Missing version to Product.create',
    },
    { user  => 'admin',
      args  => { name => '', version => PROD_VERSION, description => DESCRIPTION },
      error => 'You must enter a name',
      test  => 'Name to Product.create cannot be empty',
    },
    { user  => 'admin',
      args  => { name => random_string(20), version => PROD_VERSION, description => '' },
      error => 'You must enter a description',
      test  => 'Description to Product.create cannot be empty',
    },
    { user  => 'admin',
      args  => { name => random_string(20), version => '', description => DESCRIPTION },
      error => 'You must enter a valid version',
      test  => 'Version to Product.create cannot be empty',
    },
    { user  => 'admin',
      args  => { name => random_string(20000), version => PROD_VERSION,
                 description => DESCRIPTION },
      error => 'The name of a product is limited',
      test  => 'Name to Product.create too long',
    },
    { user  => 'admin',
      args  => { name => 'Another Product', version => PROD_VERSION,
                 description => DESCRIPTION },
      error => 'already exists',
      test  => 'Name to Product.create already exists',
    },
    { user  => 'admin',
      args  => { name => 'aNoThEr Product', version => PROD_VERSION,
                 description => DESCRIPTION },
      error => 'differs from existing product',
      test  => 'Name to Product.create already exists but with a different case',
    },
);

# FIXME - Should be: if (classifications enabled).
# But there is currently now way to query the value of a parameter via WS.
if (0) {
    push(@tests,
        { user  => 'admin',
          args  => { name => random_string(20), version => PROD_VERSION,
                     description => DESCRIPTION, has_unconfirmed => 1,
                     classification => '', default_milestone => '2.0',
                     is_open => 1, create_series => 1 },
          error => 'You must select/enter a classification',
          test  => 'Passing an empty classification to Product.create fails',
        },
        { user  => 'admin',
          args  => { name => random_string(20), version => PROD_VERSION,
                     description => DESCRIPTION, has_unconfirmed => 1,
                     classification => random_string(10), default_milestone => '2.0',
                     is_open => 1, create_series => 1 },
          error => 'You must select/enter a classification',
          test  => 'Passing an invalid classification to Product.create fails',
        },
    )
}

$jsonrpc_get->bz_call_fail('Product.create',
    { name => random_string(20), version => PROD_VERSION,
      description => 'Created with JSON-RPC via GET' },
    'must use HTTP POST', 'Product.create fails over GET');

foreach my $rpc ($xmlrpc, $jsonrpc) {
    # Tests which work must be called from here,
    # to avoid creating twice the same product.
    my @all_tests = (@tests,
        { user  => 'admin',
          args  => { name => random_string(20), version => PROD_VERSION,
                     description => DESCRIPTION },
          test  => 'Passing the name, description and version only works',
        },
        { user  => 'admin',
          args  => { name => random_string(20), version => PROD_VERSION,
                     description => DESCRIPTION, has_unconfirmed => 1,
                     classification => 'Class2_QA', default_milestone => '2.0',
                     is_open => 1, create_series => 1 },
          test  => 'Passing all arguments works',
        },
        { user  => 'admin',
          args  => { name => random_string(20), version => PROD_VERSION,
                     description => DESCRIPTION, has_unconfirmed => 0,
                     classification => 'Class2_QA', default_milestone => '2.0',
                     is_open => 0, create_series => 0 },
          test  => 'Passing null values works',
        },
        { user  => 'admin',
          args  => { name => random_string(20), version => PROD_VERSION,
                     description => DESCRIPTION, has_unconfirmed => 1,
                     classification => 'Class2_QA', default_milestone => '',
                     is_open => 1, create_series => 1 },
          test  => 'Passing an empty default milestone works (falls back to "---")',
        },
    );
    $rpc->bz_run_tests(tests => \@all_tests, method => 'Product.create',
                       post_success => \&post_success);
}
