<commit_before>use t::common;
use parent qw(Test::Class);

use JSON qw(encode_json decode_json);

my $quests_data = {
    1 => {
        name    => 'name_1',
        user    => 'user_1',
        status  => 'open',
    },
    2 => {
        name    => 'name_2',
        user    => 'user_2',
        status  => 'open',
    },
    3 => {
        name    => 'name_3',
        user    => 'user_3',
        status  => 'closed',
    },
};


#--- Init
my $quests = Play::Quests->new;
my $collection = $quests->collection;
my $ids;
sub setup :Tests(setup) {

    #--- Delete all
    $collection->remove({});

    #-- Insert
    foreach ( keys %$quests_data ) {
        delete $quests_data->{$_}->{_id};
        my $OID = $collection->insert( $quests_data->{$_} ); # MongoDB::OID
        $quests_data->{$_}->{_id} = $OID->to_string;
        $ids->{ $_ } = $OID;
    }
}

sub perl_quest_list :Test(1) {
    cmp_deeply(
        [ sort { $a->{_id} cmp $b->{_id} } @{ $quests->list({}) } ],
        [ sort { $a->{_id} cmp $b->{_id} } values %$quests_data ],
    );
}

sub quest_list :Tests {
    my $response    = dancer_response GET => '/api/quests';
    is $response->{status}, 200, 'http code';

    cmp_deeply
        [ sort { $a->{_id} cmp $b->{_id} } @{ decode_json( $response->{content} ) } ],
        [ sort { $a->{_id} cmp $b->{_id} } values %$quests_data ],
        'json';
}

sub quest_list_filtering :Tests {
    my $response    = dancer_response GET => '/api/quests', { params => { status => 'closed' } };

    is $response->{status}, 200, 'http code';

    cmp_deeply
        decode_json( $response->{content} ),
        [ $quests_data->{3} ],
        'json';
}

sub single_quest :Tests {
    my $id          =  $quests_data->{1}->{_id};
    my $response    = dancer_response GET => '/api/quest/'.$id;

    cmp_deeply(
        decode_json( $response->{content} ),
        $quests_data->{1}
    );
}

sub edit_quest :Tests {
    my $edited_quest = $quests_data->{1};
    my $id          = $edited_quest->{_id};
    local $edited_quest->{name} = 'name_11'; # Change

    #--
    my $old_login = Dancer::session->{login};
    Dancer::session login => $edited_quest->{user};

    my $response    = dancer_response PUT => '/api/quest/'.$id, { params => { name => $edited_quest->{name} } };

    #--
    my $subtestname = 'Edit specified quest, status - OK';
    my $got         = $response->{status};
    my $expect      = 200;
    is $got, $expect, $subtestname;

    #--
    $subtestname = 'Edit specified quest - OK';
    $got         = decode_json( $response->{content} );
                   delete $got->{id};
    $expect      = { result  => 'ok' };
    cmp_deeply $got, $expect, $subtestname;

    #---
    $subtestname    = 'Edit specified quest, check updated - OK';
    $got            = $collection->find_one({
                        _id => MongoDB::OID->new(value => $id)
                      });
                      Play::Quests::_prepare_quest( undef, $got );
    $expect         = $edited_quest;
    cmp_deeply $got, $expect, $subtestname;

    #-- restore session login
    Dancer::session( login => $old_login ) if $old_login;
}


sub add_quest :Tests {
    my $user = 'user_4';
    my $new_record = {
        user    => $user,
        name    => 'name_4',
        status  => 'open',
    };

    #---
    my $old_login = Dancer::session->{login};
    Dancer::session login => $user;

    my $response    = dancer_response POST => '/api/quest', { params => $new_record };

    #--
    my $subtestname = 'Add new, status - OK';
    my $got         = $response->{status};
    my $expect      = 200;
    is $got, $expect, $subtestname;

    if ( ref $response->{content} eq 'GLOB' ) {
        my $fh = $response->{content};
        local $/ = undef;
        $response->{content} = [ <$fh> ];
    }

    #--
    $subtestname = 'Add new, data - OK';
    $got         = decode_json( $response->{content} );
    my $got_id = delete $got->{id};
    $expect      = { result  => 'ok' };
    cmp_deeply $got, $expect, $subtestname;

    #---
    $subtestname    = 'Add new, check inserted - OK';
    $got            = $collection->find_one( $new_record );
    Play::Quests::_prepare_quest( undef, $got );
    $new_record->{_id} = $got_id;
    $expect         = $new_record;
    cmp_deeply $got, $expect, $subtestname;

    #-- restore session login
    Dancer::session( login => $old_login ) if $old_login;

}

sub delete_quest :Tests {
    my $id_to_remove;
    my $user;
    {
        my $list_before_resp = dancer_response GET => '/api/quests';
        my $result = decode_json($list_before_resp->{content});
        is scalar @$result, 3;
        $id_to_remove = $result->[1]{_id};
        $user = $result->[1]{user};<commit_msg>more quests.t refactorings and simplifications<commit_after>use t::common;
use parent qw(Test::Class);

use JSON qw(encode_json decode_json);

my $quests_data = {
    1 => {
        name    => 'name_1',
        user    => 'user_1',
        status  => 'open',
    },
    2 => {
        name    => 'name_2',
        user    => 'user_2',
        status  => 'open',
    },
    3 => {
        name    => 'name_3',
        user    => 'user_3',
        status  => 'closed',
    },
};


sub setup :Tests(setup) {

    my $quests = Play::Quests->new;

    Dancer::session login => undef;
    $quests->collection->remove({});

    # insert quests to DB
    for (keys %$quests_data) {
        delete $quests_data->{$_}->{_id};
        my $OID = $quests->collection->insert( $quests_data->{$_} ); # MongoDB::OID
        $quests_data->{$_}->{_id} = $OID->to_string;
    }
}

sub perl_quest_list :Test(1) {
    cmp_deeply(
        [ sort { $a->{_id} cmp $b->{_id} } @{ Play::Quests->new->list({}) } ],
        [ sort { $a->{_id} cmp $b->{_id} } values %$quests_data ],
    );
}

sub quest_list :Tests {
    my $response    = dancer_response GET => '/api/quests';
    is $response->{status}, 200, 'http code';

    cmp_deeply
        [ sort { $a->{_id} cmp $b->{_id} } @{ decode_json( $response->{content} ) } ],
        [ sort { $a->{_id} cmp $b->{_id} } values %$quests_data ],
        'json';
}

sub quest_list_filtering :Tests {
    my $response    = dancer_response GET => '/api/quests', { params => { status => 'closed' } };

    is $response->{status}, 200, 'http code';

    cmp_deeply
        decode_json( $response->{content} ),
        [ $quests_data->{3} ],
        'json';
}

sub single_quest :Tests {
    my $id          =  $quests_data->{1}->{_id};
    my $response    = dancer_response GET => '/api/quest/'.$id;

    cmp_deeply(
        decode_json( $response->{content} ),
        $quests_data->{1}
    );
}

sub edit_quest :Tests {
    my $edited_quest = $quests_data->{1};
    my $id          = $edited_quest->{_id};
    local $edited_quest->{name} = 'name_11'; # Change

    Dancer::session login => $edited_quest->{user};

    my $response = dancer_response PUT => "/api/quest/$id", { params => { name => $edited_quest->{name} } };
    is $response->status, 200, 'status - OK';

    cmp_deeply decode_json($response->content), { result => 'ok', id => $id }, 'json';

    my $get_response = dancer_response GET => "/api/quest/$id";
    is $get_response->status, 200;
    cmp_deeply decode_json($get_response->content), $edited_quest;
}


sub add_quest :Tests {
    my $user = 'user_4';
    my $new_record = {
        user    => $user,
        name    => 'name_4',
        status  => 'open',
    };

    Dancer::session login => $user;

    my $response    = dancer_response POST => '/api/quest', { params => $new_record };

    is $response->status, 200, 'status code';

    if (ref $response->content eq 'GLOB') {
        my $fh = $response->content;
        local $/ = undef;
        $response->content(join '', <$fh>);
    }

    cmp_deeply
        decode_json($response->content),
        { result => 'ok', id => re('^\S+$') },
        'response';

    my $id = decode_json($response->content)->{id};

    my $get_response = dancer_response GET => "/api/quest/$id";
    is $get_response->status, 200;
    my $got_quest = decode_json($get_response->content);
    delete $got_quest->{_id};
    cmp_deeply $got_quest, $new_record;
}

sub delete_quest :Tests {
    my $id_to_remove;
    my $user;
    {
        my $list_before_resp = dancer_response GET => '/api/quests';
        my $result = decode_json($list_before_resp->{content});
        is scalar @$result, 3;
        $id_to_remove = $result->[1]{_id};
        $user = $result->[1]{user};
{'fraction_non_alphanumeric': 0.1851284468536413, 'fraction_numerical': 0.008484562809333018, 'mean_word_length': 2.271781033153431, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 178, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1622970', 'n_tokens_mistral': 3114, 'n_tokens_neox': 2973, 'n_words': 631}