diff --git a/lib/gitea.ex b/lib/gitea.ex index ef5509e..be78463 100644 --- a/lib/gitea.ex +++ b/lib/gitea.ex @@ -47,6 +47,33 @@ defmodule Gitea do Gitea.Http.post(url, params) end + @doc """ + Create an organisation on Gitea. + The second argument opts is a keyword list value + and define the description, full_name and visibility + """ + @spec remote_org_create(%{ + required(:username) => String.t(), + optional(:description) => String.t(), + optional(:full_name) => String.t(), + optional(:visibility) => String.t() + }) :: {:ok, map} | {:error, any} + def remote_org_create(params) do + url = api_base_url() <> "orgs" + + Gitea.Http.post(url, params) + end + + @doc """ + Delete an organisation on Gitea. + """ + @spec remote_org_delete(String.t()) :: {:ok, map} | {:error, any} + def remote_org_delete(org_name) do + url = api_base_url() <> "orgs/#{org_name}" + + Gitea.Http.delete(url) + end + @doc """ `remote_repo_delete/2` accepts two arguments: `org_name` and `repo_name`. It deletes the repo on the remote `Gitea` instance as defined diff --git a/lib/http.ex b/lib/http.ex index 5338746..40af4ac 100644 --- a/lib/http.ex +++ b/lib/http.ex @@ -40,10 +40,15 @@ defmodule Gitea.Http do """ @spec parse_body_response({atom, String.t()} | {:error, any}) :: {:ok, map} | {:error, any} def parse_body_response({:error, err}), do: {:error, err} + # Deleting a repository or an organisation returns an empty string for the body value + # Instead of returning {:error, :no_body) (see next parse_body_response definition) + # the function returns {:ok, response} when the status code response is 204 + # see https://github.com/dwyl/gitea/pull/8#discussion_r874618485 + def parse_body_response({:ok, response = %{status_code: 204}}), do: {:ok, response} def parse_body_response({:ok, response}) do - # Logger.debug(response) # very noisy! body = Map.get(response, :body) + if body == nil || byte_size(body) == 0 do Logger.warning("GiteaHttp.parse_body_response: response body is nil!") {:error, :no_body} @@ -63,6 +68,7 @@ defmodule Gitea.Http do @spec get(String.t()) :: {:ok, map} | {:error, any} def get(url) do Logger.debug("GiteaHttp.get #{url}") + inject_poison().get(url, json_headers()) |> parse_body_response() end @@ -94,8 +100,9 @@ defmodule Gitea.Http do # Logger.debug("raw_markdown: #{raw_markdown}") headers = [ {"Accept", "text/html"}, - auth_header(), + auth_header() ] + inject_poison().post(url, raw_markdown, headers) end @@ -109,6 +116,7 @@ defmodule Gitea.Http do def post(url, params \\ %{}) do Logger.debug("GiteaHttp.post #{url}") body = Jason.encode!(params) + inject_poison().post(url, body, json_headers()) |> parse_body_response() end @@ -120,6 +128,7 @@ defmodule Gitea.Http do @spec delete(String.t()) :: {:ok, map} | {:error, any} def delete(url) do Logger.debug("GiteaHttp.delete #{url}") + inject_poison().delete(url <> "?token=#{access_token()}") |> parse_body_response() end diff --git a/lib/httpoison_mock.ex b/lib/httpoison_mock.ex index 126aa4c..59ddc29 100644 --- a/lib/httpoison_mock.ex +++ b/lib/httpoison_mock.ex @@ -102,16 +102,24 @@ defmodule Gitea.HTTPoisonMock do def post(url, body, headers) do Logger.debug("Gitea.HTTPoisonMock.post/3 #{url}") - if String.contains?(url, "markdown/raw") do - post_raw_html(url, body, headers) - else - body_map = Jason.decode!(body) |> Useful.atomize_map_keys() + cond do + url =~ "markdown/raw" -> + post_raw_html(url, body, headers) - response_body = - make_repo_create_post_response_body(body_map.name) - |> Jason.encode!() + url =~ "/repo" -> + body_map = Jason.decode!(body) |> Useful.atomize_map_keys() - {:ok, %HTTPoison.Response{body: response_body, status_code: 200}} + response_body = + make_repo_create_post_response_body(body_map.name) + |> Jason.encode!() + + {:ok, %HTTPoison.Response{body: response_body, status_code: 200}} + + url =~ "/orgs" -> + {:ok, %HTTPoison.Response{body: Jason.encode!(%{username: "new_org"}), status_code: 200}} + + true -> + {:ok, %HTTPoison.Response{body: Jason.encode!(""), status_code: 404}} end end @@ -135,11 +143,22 @@ defmodule Gitea.HTTPoisonMock do """ def delete(url) do Logger.debug("Gitea.HTTPoisonMock.delete/1 #{url}") + # check delete request endpooints + cond do + # match delete org + url =~ "/orgs" -> + {:ok, + %HTTPoison.Response{ + body: "", + status_code: 204 + }} - {:ok, - %HTTPoison.Response{ - body: Jason.encode!(%{deleted: List.first(String.split(url, "?"))}), - status_code: 200 - }} + true -> + {:ok, + %HTTPoison.Response{ + body: Jason.encode!(%{deleted: List.first(String.split(url, "?"))}), + status_code: 200 + }} + end end end diff --git a/test/gitea_test.exs b/test/gitea_test.exs index 7ea66c4..c9ecec0 100644 --- a/test/gitea_test.exs +++ b/test/gitea_test.exs @@ -40,6 +40,24 @@ defmodule GiteaTest do Gitea.remote_repo_delete(org_name, repo_name) end + test "remote_org_create\2 create a new organistaion" do + org_name = "new_org" + + params = %{ + username: "new_org", + description: "org description", + full_name: "new organisation", + visibility: "public" + } + + {:ok, response} = Gitea.remote_org_create(params) + + assert response.username + # delete organisation to allow test to run again + {:ok, response_delete} = Gitea.remote_org_delete(org_name) + assert response_delete.status_code == 204 + end + test "remote_repo_create/3 creates a new repo on the gitea server" do org_name = "myorg" repo_name = test_repo() diff --git a/test/httpoison_mock_test.exs b/test/httpoison_mock_test.exs index a4be492..3f940e9 100644 --- a/test/httpoison_mock_test.exs +++ b/test/httpoison_mock_test.exs @@ -16,9 +16,9 @@ defmodule HttPoisonMockTest do assert status == 200 end - test "Gitea.HTTPoisonMock.post any url should return status 200" do + test "Gitea.HTTPoisonMock.post /repos/org_name should return status 200" do {:ok, %HTTPoison.Response{status_code: status, body: resp_body}} = - Gitea.HTTPoisonMock.post("hi", Jason.encode!(%{name: "simon"}), "any-header") + Gitea.HTTPoisonMock.post("/repos/myorg", Jason.encode!(%{name: "simon"}), "any-header") assert status == 200 body_map = Jason.decode!(resp_body) |> Useful.atomize_map_keys() @@ -33,7 +33,15 @@ defmodule HttPoisonMockTest do test "Gitea.HTTPoisonMock.post when url is markdown/raw should return status 200" do {:ok, %HTTPoison.Response{status_code: status, body: body}} = Gitea.HTTPoisonMock.post("markdown/raw", "any", "any") + assert status == 200 assert body == Gitea.HTTPoisonMock.raw_html() end + + test "Gitea.HTTPoisonMock.post when url is not supported should return status 404" do + {:ok, %HTTPoison.Response{status_code: status}} = + Gitea.HTTPoisonMock.post("/not-defined", "any", "any") + + assert status == 404 + end end