<commit_before>%%%-------------------------------------------------------------------
%%% @author <NAME>
%%% @copyright (C) 2015 ACK CYFRONET AGH
%%% This software is released under the MIT license
%%% cited in 'LICENSE.txt'.
%%% @end
%%%-------------------------------------------------------------------
%%% @doc
%%% REST and CDMI tests
%%% @end
%%%-------------------------------------------------------------------
-module(rest_test_SUITE).
-author("<NAME>").

-include("global_definitions.hrl").
-include("proto/common/handshake_messages.hrl").
-include("modules/fslogic/fslogic_common.hrl").
-include_lib("ctool/include/aai/aai.hrl").
-include_lib("ctool/include/errors.hrl").
-include_lib("ctool/include/http/headers.hrl").
-include_lib("ctool/include/logging.hrl").
-include_lib("ctool/include/test/assertions.hrl").
-include_lib("ctool/include/test/performance.hrl").
-include_lib("ctool/include/test/test_utils.hrl").

%% API
-export([all/0, init_per_suite/1, init_per_testcase/2, end_per_testcase/2, end_per_suite/1]).

-export([
    token_auth/1,
    internal_error_when_handler_crashes/1,
    custom_error_when_handler_throws_error/1
]).


all() -> ?ALL([
    token_auth,
    internal_error_when_handler_crashes,
    custom_error_when_handler_throws_error
]).

-define(USER_ID, <<"test_id">>).
-define(USER_FULL_NAME, <<"test_name">>).

-define(SPACE_ID, <<"space0">>).
-define(SPACE_NAME, <<"Space 0">>).

-define(PROVIDER_ID, <<"provider1">>).

%%%===================================================================
%%% Test functions
%%%===================================================================

token_auth(Config) ->
    % given
    [Worker | _] = ?config(op_worker_nodes, Config),
    Endpoint = rest_endpoint(Worker),

    SerializedToken = initializer:create_token(?USER_ID),

    % when
    AuthFail = do_request(Config, get, Endpoint ++ "files", #{?HDR_X_AUTH_TOKEN => <<"invalid">>}),
    AuthSuccess1 = do_request(Config, get, Endpoint ++ "files", #{?HDR_X_AUTH_TOKEN => SerializedToken}),
    AuthSuccess3 = do_request(Config, get, Endpoint ++ "files", #{?HDR_AUTHORIZATION => <<"Bearer ", SerializedToken/binary>>}),
    %% @todo VFS-5554 Deprecated, included for backward compatibility
    AuthSuccess2 = do_request(Config, get, Endpoint ++ "files", #{?HDR_MACAROON => SerializedToken}),

    % then
    ?assertMatch({ok, 401, _, _}, AuthFail),
    ?assertMatch({ok, 200, _, _}, AuthSuccess1),
    ?assertMatch({ok, 200, _, _}, AuthSuccess2),
    ?assertMatch({ok, 200, _, _}, AuthSuccess3).

internal_error_when_handler_crashes(Config) ->
    % given
    Workers = [Worker | _] = ?config(op_worker_nodes, Config),
    Endpoint = rest_endpoint(Worker),
    test_utils:mock_expect(Workers, op_space, get, fun test_crash/2),

    % when
    {ok, Status, _, _} = do_request(Config, get, Endpoint ++ "spaces"),

    % then
    ?assertEqual(500, Status).

custom_error_when_handler_throws_error(Config) ->
    % given
    Workers = [Worker | _] = ?config(op_worker_nodes, Config),
    Endpoint = rest_endpoint(Worker),
    test_utils:mock_expect(Workers, op_space, get, fun(_, _) -> throw(?ERROR_BAD_VALUE_JSON(<<"dummy">>)) end),

    % when
    {ok, Status, _, Body} = do_request(Config, get, Endpoint ++ "spaces"),

    % then
    ExpRestError = rest_test_utils:get_rest_error(?ERROR_BAD_VALUE_JSON(<<"dummy">>)),
    ?assertMatch(ExpRestError, {Status, json_utils:decode(Body)}).


%%%===================================================================
%%% SetUp and TearDown functions
%%%===================================================================

init_per_suite(Config) ->
    Posthook = fun(NewConfig) ->
        [Worker | _] = ?config(op_worker_nodes, NewConfig),
        initializer:clear_subscriptions(Worker),
        NewConfig
    end,
    [{?ENV_UP_POSTHOOK, Posthook}, {?LOAD_MODULES, [initializer]} | Config].


init_per_testcase(Case, Config) when
    Case =:= internal_error_when_handler_crashes;
    Case =:= custom_error_when_handler_throws_error
->
    Workers = ?config(op_worker_nodes, Config),
    ssl:start(),
    hackney:start(),
    test_utils:mock_new(Workers, op_space),
    test_utils:mock_expect(Workers, op_space, authorize, fun(_, _) -> true end),
    mock_provider_id(Config),
    Config;
init_per_testcase(_Case, Config) ->
    ssl:start(),
    hackney:start(),
    mock_provider_id(Config),
    mock_provider_logic(Config),
    mock_space_logic(Config),
    mock_user_logic(Config),
    Config.

end_per_testcase(Case, Config) when
    Case =:= internal_error_when_handler_crashes;
    Case =:= custom_error_when_handler_throws_error
->
    Workers = ?config(op_worker_nodes, Config),
    test_utils:mock_unload(Workers, op_space),
    unmock_provider_id(Config),
    hackney:stop(),
    ssl:stop();
end_per_testcase(_Case, Config) ->
    unmock_provider_id(Config),
    unmock_provider_logic(Config),
    unmock_space_logic(Config),
    unmock_user_logic(Config),
    hackney:stop(),
    ssl:stop().


end_per_suite(_) ->
    ok.

%%%===================================================================
%%% Internal functions
%%%===================================================================

% Performs a single request using http_client
do_request(Config, Method, URL) ->
    do_request(Config, Method, URL, #{}).
do_request(Config, Method, URL, Headers) -><commit_msg>VFS-5930 fix failing rest_test_SUITE tests<commit_after>%%%-------------------------------------------------------------------
%%% @author <NAME>
%%% @copyright (C) 2015 ACK CYFRONET AGH
%%% This software is released under the MIT license
%%% cited in 'LICENSE.txt'.
%%% @end
%%%-------------------------------------------------------------------
%%% @doc
%%% REST and CDMI tests
%%% @end
%%%-------------------------------------------------------------------
-module(rest_test_SUITE).
-author("<NAME>").

-include("global_definitions.hrl").
-include("proto/common/handshake_messages.hrl").
-include("modules/fslogic/fslogic_common.hrl").
-include_lib("ctool/include/aai/aai.hrl").
-include_lib("ctool/include/errors.hrl").
-include_lib("ctool/include/http/headers.hrl").
-include_lib("ctool/include/logging.hrl").
-include_lib("ctool/include/test/assertions.hrl").
-include_lib("ctool/include/test/performance.hrl").
-include_lib("ctool/include/test/test_utils.hrl").

%% API
-export([all/0, init_per_suite/1, init_per_testcase/2, end_per_testcase/2, end_per_suite/1]).

-export([
    token_auth/1,
    internal_error_when_handler_crashes/1,
    custom_error_when_handler_throws_error/1
]).


all() -> ?ALL([
    token_auth,
    internal_error_when_handler_crashes,
    custom_error_when_handler_throws_error
]).

-define(USER_ID, <<"test_id">>).
-define(USER_FULL_NAME, <<"test_name">>).

-define(SPACE_ID, <<"space0">>).
-define(SPACE_NAME, <<"Space 0">>).

-define(PROVIDER_ID, <<"provider1">>).

%%%===================================================================
%%% Test functions
%%%===================================================================

token_auth(Config) ->
    % given
    [Worker | _] = ?config(op_worker_nodes, Config),
    Endpoint = rest_endpoint(Worker),

    SerializedToken = initializer:create_token(?USER_ID),

    % when
    AuthFail = do_request(Config, get, Endpoint ++ "files", #{?HDR_X_AUTH_TOKEN => <<"invalid">>}),
    AuthSuccess1 = do_request(Config, get, Endpoint ++ "files", #{?HDR_X_AUTH_TOKEN => SerializedToken}),
    AuthSuccess3 = do_request(Config, get, Endpoint ++ "files", #{?HDR_AUTHORIZATION => <<"Bearer ", SerializedToken/binary>>}),
    %% @todo VFS-5554 Deprecated, included for backward compatibility
    AuthSuccess2 = do_request(Config, get, Endpoint ++ "files", #{?HDR_MACAROON => SerializedToken}),

    % then
    ?assertMatch({ok, 401, _, _}, AuthFail),
    ?assertMatch({ok, 200, _, _}, AuthSuccess1),
    ?assertMatch({ok, 200, _, _}, AuthSuccess2),
    ?assertMatch({ok, 200, _, _}, AuthSuccess3).

internal_error_when_handler_crashes(Config) ->
    % given
    Workers = [Worker | _] = ?config(op_worker_nodes, Config),
    Endpoint = rest_endpoint(Worker),
    test_utils:mock_expect(Workers, space_middleware, get, fun test_crash/2),

    % when
    {ok, Status, _, _} = do_request(Config, get, Endpoint ++ "spaces"),

    % then
    ?assertEqual(500, Status).

custom_error_when_handler_throws_error(Config) ->
    % given
    Workers = [Worker | _] = ?config(op_worker_nodes, Config),
    Endpoint = rest_endpoint(Worker),
    test_utils:mock_expect(Workers, space_middleware, get, fun(_, _) -> throw(?ERROR_BAD_VALUE_JSON(<<"dummy">>)) end),

    % when
    {ok, Status, _, Body} = do_request(Config, get, Endpoint ++ "spaces"),

    % then
    ExpRestError = rest_test_utils:get_rest_error(?ERROR_BAD_VALUE_JSON(<<"dummy">>)),
    ?assertMatch(ExpRestError, {Status, json_utils:decode(Body)}).


%%%===================================================================
%%% SetUp and TearDown functions
%%%===================================================================

init_per_suite(Config) ->
    Posthook = fun(NewConfig) ->
        [Worker | _] = ?config(op_worker_nodes, NewConfig),
        initializer:clear_subscriptions(Worker),
        NewConfig
    end,
    [{?ENV_UP_POSTHOOK, Posthook}, {?LOAD_MODULES, [initializer]} | Config].


init_per_testcase(Case, Config) when
    Case =:= internal_error_when_handler_crashes;
    Case =:= custom_error_when_handler_throws_error
->
    Workers = ?config(op_worker_nodes, Config),
    ssl:start(),
    hackney:start(),
    test_utils:mock_new(Workers, space_middleware),
    test_utils:mock_expect(Workers, space_middleware, authorize, fun(_, _) -> true end),
    mock_provider_id(Config),
    Config;
init_per_testcase(_Case, Config) ->
    ssl:start(),
    hackney:start(),
    mock_provider_id(Config),
    mock_provider_logic(Config),
    mock_space_logic(Config),
    mock_user_logic(Config),
    Config.

end_per_testcase(Case, Config) when
    Case =:= internal_error_when_handler_crashes;
    Case =:= custom_error_when_handler_throws_error
->
    Workers = ?config(op_worker_nodes, Config),
    test_utils:mock_unload(Workers, space_middleware),
    unmock_provider_id(Config),
    hackney:stop(),
    ssl:stop();
end_per_testcase(_Case, Config) ->
    unmock_provider_id(Config),
    unmock_provider_logic(Config),
    unmock_space_logic(Config),
    unmock_user_logic(Config),
    hackney:stop(),
    ssl:stop().


end_per_suite(_) ->
    ok.

%%%===================================================================
%%% Internal functions
%%%===================================================================

% Performs a single request using http_client
do_request(Config, Method, URL) ->
    do_request(Config, Method, URL, #{}).
do_request(Config, Method, URL, Headers) ->
{'fraction_non_alphanumeric': 0.2531328320802005, 'fraction_numerical': 0.007982920263622018, 'mean_word_length': 4.24537487828627, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 81, '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': '4875426', 'n_tokens_mistral': 3567, 'n_tokens_neox': 3416, 'n_words': 542}