#!/usr/local/cpanel/3rdparty/bin/perl -w

# cpanel - t/medium/Cpanel-API-SiteQuality.t       Copyright 2024 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

package t::medium::Cpanel::API::SiteQuality;

use cPstrict;
use Test::Cpanel::Policy;

use Test2::V0;
use Test2::Tools::Explain;
use Test2::Tools::Compare;
use Test2::Plugin::NoWarnings;
use Test2::Tools::Exception;
use Test::MockModule;
use Test::MockFile;

use Cpanel::Args   ();
use Cpanel::Result ();

use Cpanel::API::SiteQuality ();

use base qw(Test::Class);

my $mock_errorlog = Test::MockFile->file( '/usr/local/cpanel/logs/error_log', {} );

__PACKAGE__->new()->runtests() if !caller;

#----------------------------------------------------------------------

sub create_site_quality_user : Tests(7) {

    my $m_auth = Test::MockModule->new('Cpanel::Koality::Auth');
    $m_auth->redefine( 'new' => sub { return bless {}, shift } );

    my ( $app_token, $enabled, $username, $die ) = ( 'abcd1234', 1, 'kuser', 0 );
    $m_auth->redefine( 'create_user'  => sub { die 'Died' if $die; return bless { app_token => $app_token, enabled => $enabled, username => $username }, 'Cpanel::Koality::MockUser'; } );
    $m_auth->redefine( 'auth_session' => 1 );

    my $args;
    my $result = Cpanel::Result->new();

    $args = Cpanel::Args->new();
    ok( dies { Cpanel::API::SiteQuality::create_site_quality_user( $args, $result ) }, "Dies when the required attributes are not set." );

    $args = Cpanel::Args->new( { foobar => 'bingo' } );
    ok( dies { Cpanel::API::SiteQuality::create_site_quality_user( $args, $result ) }, "Dies when the required attributes are not set and junk is passed as args" );

    $args = Cpanel::Args->new( { password => 'password' } );
    ok( dies { Cpanel::API::SiteQuality::create_site_quality_user( $args, $result ) }, "Dies when the required attributes are not set and only optional args are passed" );

    $args = Cpanel::Args->new( { email => 'foo@bar.baz', password => 'password' } );
    ok( lives { Cpanel::API::SiteQuality::create_site_quality_user( $args, $result ) }, "Lives when the required attributes are set." );

    $args = Cpanel::Args->new( { email => 'foo@bar.baz' } );
    ok( lives { Cpanel::API::SiteQuality::create_site_quality_user( $args, $result ) }, "Lives when optional attributes are not set." );

    $args = Cpanel::Args->new( { email => 'foo@bar.baz' } );
    $die  = 1;
    ok( dies { Cpanel::API::SiteQuality::create_site_quality_user( $args, $result ) }, "Dies if create_user dies." );
    $die = 0;

    my $expected_hr = {
        app_token => 'abcd1234',
        enabled   => 1,
        username  => 'kuser',
    };

    $args = Cpanel::Args->new( { email => 'foo@bar.baz' } );
    Cpanel::API::SiteQuality::create_site_quality_user( $args, $result );
    is( $expected_hr, $result->data(), "Got expected returns with the happy path." );

    return;
}

sub delete_site_quality_user : Tests(9) {

    my ( $die, $deleted, $args ) = ( 0, );
    local $Cpanel::user = 'cp_user';

    my $m_auth = Test::MockModule->new('Cpanel::Koality::Auth');
    $m_auth->redefine( new      => sub { return bless {}, shift } );
    $m_auth->redefine( get_user => sub { return bless {}, 'Cpanel::Koality::User'; } );
    $m_auth->redefine(
        delete_user => sub {
            die if $die;
            return $deleted;
        }
    );

    my $result = Cpanel::Result->new();

    $deleted = 1;
    $args    = Cpanel::Args->new();
    ok( lives { Cpanel::API::SiteQuality::delete_site_quality_user( $args, $result ) }, "Lives when no arguments are set." );
    is( $result->data->{deleted}, 1, "Got expected result for deleted." );

    $args = Cpanel::Args->new( { some => 'junk' } );
    ok( lives { Cpanel::API::SiteQuality::delete_site_quality_user( $args, $result ) }, "Lives when junk arguments are passed in." );
    is( $result->data->{deleted}, 1, "Got expected result for deleted." );

    $deleted = 0;
    ok( lives { Cpanel::API::SiteQuality::delete_site_quality_user( $args, $result ) }, "Lives if the account was not deleted." );
    is( $result->data->{deleted}, 0, "Got expected result for deleted." );
    is( $result->errors->@*,      1, "... but get an error about it." );

    $die = 1;
    ok( dies { Cpanel::API::SiteQuality::delete_site_quality_user( $args, $result ) }, "Dies if the backend call dies." );
    is( $result->errors->@*, 1, "... and get an error about it." );

    return 1;
}

sub is_site_quality_user_enabled : Tests(5) {

    my ( $die, $enabled ) = 0;

    my $m_auth = Test::MockModule->new('Cpanel::Koality::Auth');
    $m_auth->redefine( 'new' => sub { return bless {}, shift } );
    $m_auth->redefine( 'get_user' => sub { die 'Died' if $die; return bless { enabled => $enabled }, 'Cpanel::Koality::MockUser'; } );

    my $args;
    my $result = Cpanel::Result->new();

    $enabled = 1;
    $args    = Cpanel::Args->new();
    ok( lives { Cpanel::API::SiteQuality::is_site_quality_user_enabled( $args, $result ) }, "Lives when no arguments are set." );

    is( $result->data->{enabled}, 1, "Got expected result for enabled." );

    $enabled = 0;
    $args    = Cpanel::Args->new( { some => 'junk' } );
    ok( lives { Cpanel::API::SiteQuality::is_site_quality_user_enabled( $args, $result ) }, "Lives when junk arguments are passed in." );
    is( $result->data->{enabled}, 0, "Got expected result for enabled." );

    $die = 1;
    Cpanel::API::SiteQuality::is_site_quality_user_enabled( $args, $result );
    is( $result->errors->@*, 1, "Got errors when the backend dies." );

    return 1;
}

sub get_app_token : Tests(5) {

    my ( $die, $app_token ) = ( 0, '' );
    local $Cpanel::user = 'cp_user';

    my $mock_file = Test::MockFile->file( '/var/cpanel/use_koality_stage', undef );

    my $mock_base = Test::MockModule->new('Cpanel::Koality::Base');
    $mock_base->redefine( _build__check_privs => sub ($) { return 1; } );

    my $m_val = Test::MockModule->new('Cpanel::Validate::Username');
    $m_val->redefine( 'user_exists_or_die' => sub { return 1 } );

    my $m_user = Test::MockModule->new('Cpanel::Koality::User');
    $m_user->redefine(
        'new' => sub {
            die 'Died' if $die;
            return bless { app_token => $app_token }, 'Cpanel::Koality::MockUser';
        }
    );

    my $args;
    my $result = Cpanel::Result->new();

    $app_token = 'abcd1234';
    $args      = Cpanel::Args->new();
    ok( lives { Cpanel::API::SiteQuality::get_app_token( $args, $result ) }, "Lives when no arguments are set." );
    is( $result->data->{app_token}, 'abcd1234', "Got expected result for session_token." );

    $app_token = '1234abcd';
    $args      = Cpanel::Args->new( { some => 'junk' } );
    ok( lives { Cpanel::API::SiteQuality::get_app_token( $args, $result ) }, "Lives when junk arguments are passed in." );
    is( $result->data->{app_token}, '1234abcd', "Got expected result for session_token." );

    my $mock_locale_user = Test::MockModule->new('Cpanel::Locale::Utils::User');
    $mock_locale_user->redefine(
        'get_user_locale' => sub {
            return 'en';
        }
    );

    my $mock_companyid = Test::MockModule->new('Cpanel::License::CompanyID');
    $mock_companyid->redefine(
        'get_company_id' => sub {
            return 42;
        }
    );

    my $mock_serverid = Test::MockModule->new('Cpanel::Plugins::ServerId');
    $mock_serverid->redefine(
        'get_server_id' => sub {
            return "010101";
        }
    );

    $die = 1;
    Cpanel::API::SiteQuality::is_site_quality_user_enabled( $args, $result );
    is( $result->errors->@*, 1, "Got errors when the backend dies." );

    return 1;
}

sub has_site_quality_user : Tests(6) {

    my ( $die, $app_token ) = ( 0, '' );

    local $Cpanel::user = 'cp_user';
    my $m_val = Test::MockModule->new('Cpanel::Validate::Username');
    $m_val->redefine( 'user_exists_or_die' => sub { return 1 } );

    my $m_user = Test::MockModule->new('Cpanel::Koality::User');
    $m_user->redefine(
        'new' => sub {
            die 'Died' if $die;
            return bless { app_token => $app_token }, 'Cpanel::Koality::MockUser';
        }
    );

    my $args;
    my $result = Cpanel::Result->new();

    $app_token = 'abcd1234';
    $args      = Cpanel::Args->new();
    ok( lives { Cpanel::API::SiteQuality::has_site_quality_user( $args, $result ) }, "Lives when no arguments are set." );
    is( $result->data->{has_site_quality_user}, '1', "Got expected result when user exists." );

    $app_token = undef;
    $args      = Cpanel::Args->new();
    ok( lives { Cpanel::API::SiteQuality::has_site_quality_user( $args, $result ) }, "Lives when no arguments are set." );
    is( $result->data->{has_site_quality_user}, '0', "Got expected result when user does not exist." );

    $app_token = undef;
    $args      = Cpanel::Args->new();
    $die       = 1;
    ok( lives { Cpanel::API::SiteQuality::has_site_quality_user( $args, $result ) }, "Lives when no arguments are set and backend dies." );
    is( $result->errors->@*, 1, "Got errors when the backend dies." );

    return 1;
}

sub get_environment : Tests(4) {
    local $Cpanel::user = 'fake';
    my $mock_file = Test::MockFile->file( '/var/cpanel/use_koality_stage', undef );

    my $mock_validation = Test::MockModule->new('Cpanel::Validate::Username');
    $mock_validation->redefine( user_exists_or_die => sub { } );

    my $mock_base = Test::MockModule->new('Cpanel::Koality::Base');
    $mock_base->redefine( _build__check_privs => sub ($) { return 1; } );

    my $mock_companyid = Test::MockModule->new('Cpanel::License::CompanyID');
    $mock_companyid->redefine(
        'get_company_id' => sub {
            return 42;
        }
    );

    my $mock_serverid = Test::MockModule->new('Cpanel::Plugins::ServerId');
    $mock_serverid->redefine(
        'get_server_id' => sub {
            return "010101";
        }
    );

    my $args;
    my $result = Cpanel::Result->new();

    $args = Cpanel::Args->new();
    ok( Cpanel::API::SiteQuality::get_environment( $args, $result ), "returns success" );
    is( $result->data->{environment}, 'production', "Got production environment when the touch file is missing." );

    $mock_file->touch();
    $args = Cpanel::Args->new();
    ok( Cpanel::API::SiteQuality::get_environment( $args, $result ), "returns success" );
    is( $result->data->{environment}, 'staging', "Got staging environment when the touch file exists." );

    return 1;
}

1;

package Cpanel::Koality::MockUser;

sub new ($args) {
    return bless $args, 'Cpanel::Koality::MockUser';
}

sub app_token ($self) {
    return $self->{app_token};
}

sub enabled ($self) {
    return $self->{enabled};
}

sub koality_username ($self) {
    return $self->{username};
}

sub session_token ($self) {
    return $self->{session_token};
}

1;
