Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[77] implemented creating and deleting of a project #89

Merged
merged 9 commits into from
May 31, 2022
Merged
59 changes: 57 additions & 2 deletions lib/uffizzi/cli/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'uffizzi'
require 'uffizzi/auth_helper'
require 'uffizzi/response_helper'
require 'uffizzi/helpers/project_helper'

module Uffizzi
class Cli::Project < Thor
Expand All @@ -29,6 +30,19 @@ def set_default(project_slug)

map('set-default' => :set_default)

method_option :name, required: true
method_option :slug, default: ''
method_option :description, required: false
desc 'create', 'Create a project'
def create
run('create')
end

desc 'delete [PROJECT_SLUG]', 'Delete a project'
def delete(project_slug)
run('delete', project_slug: project_slug)
end

private

def run(command, project_slug: nil)
Expand All @@ -39,6 +53,10 @@ def run(command, project_slug: nil)
handle_list_command
when 'set-default'
handle_set_default_command(project_slug)
when 'create'
handle_create_command
when 'delete'
handle_delete_command(project_slug)
end
end

Expand All @@ -47,13 +65,44 @@ def handle_list_command
response = fetch_projects(server)

if ResponseHelper.ok?(response)
handle_succeed_response(response)
handle_list_success_response(response)
else
ResponseHelper.handle_failed_response(response)
end
end

def handle_create_command
name = options[:name]
slug = options[:slug].empty? ? Uffizzi::ProjectHelper.generate_slug(name) : options[:slug]
raise Uffizzi::Error.new('Slug must not content spaces or special characters') unless slug.match?(/^[a-zA-Z0-9\-_]+\Z/i)

server = ConfigFile.read_option(:server)
params = {
name: name,
description: options[:description],
slug: slug,
}
response = create_project(server, params)

if ResponseHelper.created?(response)
handle_create_success_response(response)
else
ResponseHelper.handle_failed_response(response)
end
end

def handle_succeed_response(response)
def handle_delete_command(project_slug)
server = ConfigFile.read_option(:server)
response = delete_project(server, project_slug)

if ResponseHelper.no_content?(response)
Uffizzi.ui.say("Project with slug #{project_slug} was deleted successfully")
else
ResponseHelper.handle_failed_response(response)
end
end

def handle_list_success_response(response)
projects = response[:body][:projects]
return Uffizzi.ui.say('No projects related to this email') if projects.empty?

Expand All @@ -76,6 +125,12 @@ def handle_succeed_set_default_response(response)
Uffizzi.ui.say('Default project has been updated.')
end

def handle_create_success_response(response)
project_name = response[:body][:project][:name]

Uffizzi.ui.say("Project #{project_name} was successfully created")
end

def print_projects(projects)
projects_list = projects.reduce('') do |acc, project|
"#{acc}#{project[:slug]}\n"
Expand Down
14 changes: 14 additions & 0 deletions lib/uffizzi/clients/api/api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ def describe_project(server, project_slug)
build_response(response)
end

def create_project(server, params)
uri = projects_uri(server)
response = http_client.make_post_request(uri, params)

build_response(response)
end

def delete_project(server, project_slug)
uri = project_uri(server, project_slug)
response = http_client.make_delete_request(uri)

build_response(response)
end

def create_credential(server, params)
uri = credentials_uri(server)
response = http_client.make_post_request(uri, params)
Expand Down
22 changes: 22 additions & 0 deletions lib/uffizzi/helpers/project_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Uffizzi
module ProjectHelper
SLUG_ENDING_LENGTH = 6
class << self
def generate_slug(name)
formatted_name = name.downcase.gsub(/ /, '-').gsub(/[^\w-]+/, '')
slug_ending = generate_random_string(SLUG_ENDING_LENGTH)

"#{formatted_name}-#{slug_ending}"
end

private

def generate_random_string(length)
hexatridecimal_base = 36
rand(hexatridecimal_base**length).to_s(hexatridecimal_base)
end
end
end
end
2 changes: 1 addition & 1 deletion man/uffizzi-config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "CONFIG" "" "April 2022" ""
.TH "CONFIG" "" "May 2022" ""
.SH "NAME"
\fBconfig\fR \- configure the Uffizzi command\-line interface (CLI)
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion man/uffizzi-login
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "UFFIZZI\-LOGIN" "" "April 2022" ""
.TH "UFFIZZI\-LOGIN" "" "May 2022" ""
.SH "NAME"
\fBuffizzi\-login\fR \- login to Uffizzi to view and manage your previews\.
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion man/uffizzi-logout
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "UFFIZZI\-LOGOUT" "" "March 2022" ""
.TH "UFFIZZI\-LOGOUT" "" "May 2022" ""
.SH "NAME"
\fBuffizzi\-logout\fR \- log out of a Uffizzi user account
.SH "SYNOPSIS"
Expand Down
50 changes: 50 additions & 0 deletions man/uffizzi-project-create
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "UFFIZZI\-PROJECT\-CREATE" "" "May 2022" ""
.SH "NAME"
\fBuffizzi\-project\-create\fR \- create a new project
.SH "SYNOPSIS"
.nf
uffizzi project create [\-\-name=NAME] [\-\-slug=SLUG]
[\-\-description=DESCRIPTION] [UFFIZZI_WIDE_FLAG \|\.\|\.\|\.]
.fi
.SH "DESCRIPTION"
.nf
Create new project\.

This command can fail for the following reasons:
\- The project \-\-description is too long\.
\- The project \-\-name flag is not specified\.
\- The project \-\-slug is malformed or used by another project\.

For more information on the uffizzi project command, see:
https:/github\.com/UffizziCloud/uffizzi_cli
.fi
.SH "FLAGS"
.nf
\-\-description=DESCRIPTION
Description for the project you want to create\. Max of 256
characters\.

\-\-name=NAME
Name for the project you want to create\.

\-\-slug=SLUG
A URL\-compatible name\. Do not include whitespaces or special characters\.
Project slugs must be globally unique across all Uffizzi projects\.
If a slug is not provided, Uffizzi will automatically generate one\.
.fi
.SH "UFFIZZI WIDE FLAGS"
.nf
These flags are available to all commands: \-\-project\. Run $ uffizzi
help for details\.
.fi
.SH "EXAMPLES"
.nf
To create a new project with name My App, project slug my\-app, and
description "My first project", run:

$ uffizzi project create \-\-name="My App" \-\-slug="my\-app" \e
\-\-description="My first project"
.fi

41 changes: 41 additions & 0 deletions man/uffizzi-project-create.ronn
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
uffizzi-project-create - create a new project
================================================================

## SYNOPSIS
uffizzi project create [--name=NAME] [--slug=SLUG]
[--description=DESCRIPTION] [UFFIZZI_WIDE_FLAG ...]

## DESCRIPTION
Create new project.

This command can fail for the following reasons:
- The project --description is too long.
- The project --name flag is not specified.
- The project --slug is malformed or used by another project.

For more information on the uffizzi project command, see:
https:/github.com/UffizziCloud/uffizzi_cli

## FLAGS
--description=DESCRIPTION
Description for the project you want to create. Max of 256
characters.

--name=NAME
Name for the project you want to create.

--slug=SLUG
A URL-compatible name. Do not include whitespaces or special characters.
Project slugs must be globally unique across all Uffizzi projects.
If a slug is not provided, Uffizzi will automatically generate one.

## UFFIZZI WIDE FLAGS
These flags are available to all commands: --project. Run $ uffizzi
help for details.

## EXAMPLES
To create a new project with name My App, project slug my-app, and
description "My first project", run:

$ uffizzi project create --name="My App" --slug="my-app" \
--description="My first project"
32 changes: 32 additions & 0 deletions man/uffizzi-project-delete
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "UFFIZZI\-PROJECT\-DELETE" "" "May 2022" ""
.SH "NAME"
\fBuffizzi\-project\-delete\fR \- delete a project
.SH "SYNOPSIS"
.nf
uffizzi project delete PROJECT_SLUG [UFFIZZI_WIDE_FLAG \|\.\|\.\|\.]
.fi
.SH "DESCRIPTION"
.nf
Deletes a project with the given project slug\.

This command can fail for the following reasons:
\- There is no project with the given project slug
\- The active account does not have permission to delete the project

For more information on Uffizzi projects, see:
https:/github\.com/UffizziCloud/uffizzi_cli
.fi
.SH "UFFIZZI WIDE FLAGS"
.nf
These flags are available to all commands: \-\-project\. Run $ uffizzi
help for details\.
.fi
.SH "EXAMPLES"
.nf
To delete a project with project slug my\-app\-xc8fw, run:

$ uffizzi project delete my\-app\-xc8fw
.fi

24 changes: 24 additions & 0 deletions man/uffizzi-project-delete.ronn
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
uffizzi-project-delete - delete a project
================================================================

## SYNOPSIS
uffizzi project delete PROJECT_SLUG [UFFIZZI_WIDE_FLAG ...]

## DESCRIPTION
Deletes a project with the given project slug.

This command can fail for the following reasons:
- There is no project with the given project slug
- The active account does not have permission to delete the project

For more information on Uffizzi projects, see:
https:/github.com/UffizziCloud/uffizzi_cli

## UFFIZZI WIDE FLAGS
These flags are available to all commands: --project. Run $ uffizzi
help for details.

## EXAMPLES
To delete a project with project slug my-app-xc8fw, run:

$ uffizzi project delete my-app-xc8fw
6 changes: 6 additions & 0 deletions test/fixtures/files/uffizzi/uffizzi_project_success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"project":
{
"slug": "project_slug_1"
}
}
12 changes: 12 additions & 0 deletions test/support/uffizzi_stub_support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ def stub_uffizzi_projects_failed(body)
stub_request(:get, url).to_return(status: 401, body: body.to_json)
end

def stub_uffizzi_project_create_success(body)
url = projects_uri(Uffizzi.configuration.server)

stub_request(:post, url).to_return(status: 201, body: body.to_json)
end

def stub_uffizzi_project_delete_success(body, project_slug)
url = project_uri(Uffizzi.configuration.server, project_slug)

stub_request(:delete, url).to_return(status: 204, body: body.to_json)
end

def stub_uffizzi_create_compose(base_url, status, body, headers)
url = compose_files_uri(base_url)

Expand Down
38 changes: 38 additions & 0 deletions test/uffizzi/cli/project_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,44 @@ def test_project_list_success
assert_requested(stubbed_uffizzi_projects)
end

def test_project_create_success
body = json_fixture('files/uffizzi/uffizzi_project_success.json')
stubbed_uffizzi_project = stub_uffizzi_project_create_success(body)
@project.options = {
name: 'name',
description: 'project description',
slug: 'project_slug_1',
}

@project.create

assert_requested(stubbed_uffizzi_project)
end

def test_project_create_invalid_slug_failure
@project.options = {
name: 'name',
description: 'project description',
slug: 'project_slug*',
}

error = assert_raises(Uffizzi::Error) do
@project.create
end

assert_equal('Slug must not content spaces or special characters', error.message)
end

def test_project_delete_success
project_slug = 'project_slug_1'
body = json_fixture('files/uffizzi/uffizzi_project_success.json')
stubbed_uffizzi_project = stub_uffizzi_project_delete_success(body, project_slug)

@project.delete(project_slug)

assert_requested(stubbed_uffizzi_project)
end

def test_project_list_success_with_one_project
body = json_fixture('files/uffizzi/uffizzi_projects_success_one_project.json')
stubbed_uffizzi_projects = stub_uffizzi_projects_success(body)
Expand Down