test_that("file queries for GitLab are built properly", {
  gl_files_query <-
    test_gqlquery_gl$files_by_org()
  expect_snapshot(
    gl_files_query
  )
  gl_file_blobs_from_repo_query <-
    test_gqlquery_gl$file_blob_from_repo()
  expect_snapshot(
    gl_file_blobs_from_repo_query
  )
  test_mocker$cache(gl_file_blobs_from_repo_query)
})

test_that("get_file_blobs_response() works", {
  mockery::stub(
    test_graphql_gitlab_priv$get_file_blobs_response,
    "self$gql_response",
    test_fixtures$gitlab_file_repo_response
  )
  gl_file_blobs_response <- test_graphql_gitlab_priv$get_file_blobs_response(
    org = "mbtests",
    repo = "graphql_tests",
    file_path = c("project_metadata.yaml", "README.md")
  )
  expect_files_gitlab_blob_response(gl_file_blobs_response)
  test_mocker$cache(gl_file_blobs_response)
})

test_that("GitLab GraphQL Engine pulls files from a group", {
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "self$gql_response",
    test_fixtures$gitlab_file_org_response
  )
  gitlab_files_response <- test_graphql_gitlab$get_files_from_org(
    org = "mbtests",
    owner_type = "organization",
    repos = NULL,
    file_paths = "meta_data.yaml",
    host_files_structure = NULL
  )
  expect_files_gitlab_from_org_response(gitlab_files_response)
  test_mocker$cache(gitlab_files_response)
})

test_that("GitLab GraphQL Engine pulls files from org by iterating over repos", {
  mockery::stub(
    test_graphql_gitlab$get_files_from_org_per_repo,
    "private$get_file_blobs_response",
    test_mocker$use("gl_file_blobs_response")
  )
  gl_files_from_org_per_repo <- test_graphql_gitlab$get_files_from_org_per_repo(
    org = "test_org",
    owner_type = "organization",
    repos_data = list("paths" = "TestProject"),
    file_paths = c("project_metadata.yaml", "README.md")
  )
  expect_files_gitlab_from_org_by_repos_response(
    response = gl_files_from_org_per_repo,
    expected_files = c("project_metadata.yaml", "README.md")
  )
  test_mocker$cache(gl_files_from_org_per_repo)
})

test_that("is query error is FALSE when response is empty (non query error)", {
  expect_false(
    test_graphql_gitlab_priv$is_query_error(list())
  )
})

test_that("GitLab GraphQL Engine switches to pulliing files per repo when owner is not an organization", {
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "self$get_files_from_org_per_repo",
    test_mocker$use("gl_files_from_org_per_repo")
  )
  gitlab_files_response <- test_graphql_gitlab$get_files_from_org(
    org = "mbtests",
    owner_type = "user",
    repos = NULL,
    file_paths = "project_metadata.yaml",
    host_files_structure = NULL
  )
  expect_files_gitlab_from_org_by_repos_response(
    response = gitlab_files_response,
    expected_files = "project_metadata.yaml"
  )
})

test_that("Gitlab GraphQL switches to pulling files per repositories when query is too complex", {
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "private$is_query_error",
    TRUE
  )
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "private$is_complexity_error",
    TRUE
  )
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "self$get_files_from_org_per_repo",
    test_mocker$use("gl_files_from_org_per_repo")
  )
  gitlab_files_response_by_repos <- test_graphql_gitlab$get_files_from_org(
    org = "mbtests",
    owner_type = "organization",
    repos = NULL,
    file_paths = c("project_metadata.yaml", "README.md"),
    host_files_structure = NULL,
    verbose = FALSE
  )
  expect_files_gitlab_from_org_by_repos_response(
    response = gitlab_files_response_by_repos,
    expected_files = c("project_metadata.yaml", "README.md")
  )
  test_mocker$cache(gitlab_files_response_by_repos)
})

test_that("Gitlab GraphQL prints messages when switching to pulling files per repositories", {
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "private$is_query_error",
    TRUE
  )
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "private$is_complexity_error",
    TRUE
  )
  mockery::stub(
    test_graphql_gitlab$get_files_from_org,
    "self$get_files_from_org_per_repo",
    test_mocker$use("gl_files_from_org_per_repo")
  )
  expect_snapshot(
    gitlab_files_response_by_repos <- test_graphql_gitlab$get_files_from_org(
      org = "mbtests",
      owner_type = "organization",
      repos = NULL,
      file_paths = c("project_metadata.yaml", "README.md"),
      host_files_structure = NULL,
      verbose = TRUE
    )
  )
})

test_that("GitLab GraphQL switches to iteration when query is too complex", {
  mockery::stub(
    test_graphql_gitlab$get_files_from_org_per_repo,
    "private$get_file_blobs_response",
    test_mocker$use("gl_file_blobs_response")
  )
  mockery::stub(
    test_graphql_gitlab$get_files_from_org_per_repo,
    "private$is_complexity_error",
    TRUE
  )
  expect_snapshot(
    files_from_org_per_repo <- test_graphql_gitlab$get_files_from_org_per_repo(
      org = "mbtests",
      owner_type = "organization",
      repos_data = list("paths" = "gitstatstesting"),
      file_paths = c("project_metadata.yaml", "README.md"),
      host_files_structure = NULL,
      verbose = TRUE
    )
  )
})

test_that("checker properly identifies gitlab files responses", {
  expect_false(
    test_graphql_gitlab_priv$response_prepared_by_iteration(
      files_response = test_mocker$use("gitlab_files_response")
    )
  )
  expect_true(
    test_graphql_gitlab_priv$response_prepared_by_iteration(
      files_response = test_mocker$use("gitlab_files_response_by_repos")
    )
  )
})

test_that("GitLab prepares table from files response", {
  gl_files_table <- test_graphql_gitlab$prepare_files_table(
    files_response = test_mocker$use("gitlab_files_response"),
    org = "mbtests"
  )
  expect_files_table(gl_files_table)
  test_mocker$cache(gl_files_table)
})

test_that("GitLab prepares table from files response prepared in alternative way", {
  gl_files_table <- test_graphql_gitlab$prepare_files_table(
    files_response = test_mocker$use("gitlab_files_response_by_repos"),
    org = "mbtests"
  )
  expect_files_table(gl_files_table)
})

test_that("get_files_content_from_orgs for GitLab works", {
  mockery::stub(
    gitlab_testhost_priv$get_files_content_from_orgs,
    "graphql_engine$prepare_files_table",
    test_mocker$use("gl_files_table")
  )
  gitlab_testhost_priv$searching_scope <- "org"
  gl_files_table <- gitlab_testhost_priv$get_files_content_from_orgs(
    file_path = "meta_data.yaml",
    verbose = FALSE
  )
  expect_files_table(
    gl_files_table, with_cols = "api_url"
  )
  test_mocker$cache(gl_files_table)
})

test_that("get_files_content_from_repos for GitLab works", {
  mockery::stub(
    gitlab_testhost_priv$get_files_content_from_repos,
    "graphql_engine$prepare_files_table",
    test_mocker$use("gl_files_table")
  )
  test_org <- "test_group"
  attr(test_org, "type") <- "organization"
  mockery::stub(
    gitlab_testhost_priv$get_files_content_from_repos,
    "graphql_engine$set_owner_type",
    test_org
  )
  gitlab_testhost_priv$searching_scope <- "repo"
  gl_files_table <- gitlab_testhost_priv$get_files_content_from_repos(
    file_path = "meta_data.yaml",
    verbose = FALSE
  )
  expect_files_table(
    gl_files_table, with_cols = "api_url"
  )
  gitlab_testhost_priv$searching_scope <- "org"
})

test_that("get_files_content_from_repos for GitLab prints message", {
  mockery::stub(
    gitlab_testhost_priv$get_files_content_from_repos,
    "graphql_engine$prepare_files_table",
    test_mocker$use("gl_files_table")
  )
  test_org <- "test_group"
  attr(test_org, "type") <- "organization"
  mockery::stub(
    gitlab_testhost_priv$get_files_content_from_repos,
    "graphql_engine$set_owner_type",
    test_org
  )
  gitlab_testhost_priv$searching_scope <- "repo"
  expect_snapshot(
    gl_files_table <- gitlab_testhost_priv$get_files_content_from_repos(
      file_path = "meta_data.yaml",
      verbose = TRUE
    )
  )
})

test_that("get_files_content makes use of files_structure", {
  mockery::stub(
    gitlab_testhost_priv$get_files_content_from_files_structure,
    "graphql_engine$prepare_files_table",
    test_mocker$use("gl_files_table")
  )
  expect_snapshot(
    files_content <- gitlab_testhost_priv$get_files_content_from_files_structure(
      files_structure = test_mocker$use("gl_files_structure_from_orgs"),
      verbose = TRUE
    )
  )
  expect_files_table(
    files_content,
    with_cols = "api_url"
  )
})

test_that("get_files_content skips if files structure is empty", {
  expect_snapshot(
    files_content <- gitlab_testhost_priv$get_files_content_from_files_structure(
      files_structure = test_mocker$use("gl_empty_files_structure"),
      verbose = TRUE
    )
  )
})
