Repository: ctreminiom/go-atlassian
Pull request #60 (2021-08-28 21:24:03)

DEV


Patch:
diff --git a/go.mod b/go.mod
index 4894318..947021f 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,6 @@ go 1.15
 
 require (
 	github.com/google/uuid v1.1.4
-	github.com/imdario/mergo v0.3.12
+	github.com/imdario/mergo v0.3.11
 	github.com/stretchr/testify v1.7.0
 )
diff --git a/go.sum b/go.sum
index 5b95777..cdab78a 100644
--- a/go.sum
+++ b/go.sum
@@ -2,10 +2,11 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/google/uuid v1.1.4 h1:0ecGp3skIrHWPNGPJDaBIghfA6Sp7Ruo2Io8eLKzWm0=
 github.com/google/uuid v1.1.4/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
-github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
diff --git a/jira/examples/workflow/delete/delete.go b/jira/examples/workflow/delete/delete.go
new file mode 100644
index 0000000..9bb5eb3
--- /dev/null
+++ b/jira/examples/workflow/delete/delete.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	var workflowID = "47e1994b-b84a-476c-84e1-2c8b0e5bb181"
+
+	response, err := atlassian.Workflow.Delete(context.Background(), workflowID)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+	}
+
+	log.Println(response.Code)
+	log.Println(response.Endpoint)
+}
diff --git a/jira/examples/workflow/gets/gets.go b/jira/examples/workflow/gets/gets.go
new file mode 100644
index 0000000..738ed0f
--- /dev/null
+++ b/jira/examples/workflow/gets/gets.go
@@ -0,0 +1,95 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	var expand = []string{
+		"transitions",         //For each workflow, returns information about the transitions inside the workflow.
+		"transitions.rules",   //For each workflow transition, returns information about its rules. Transitions are included automatically if this expand is requested.
+		"statuses",            //For each workflow, returns information about the statuses inside the workflow.
+		"statuses.properties", //For each workflow status, returns information about its properties. Statuses are included automatically if this expand is requested.
+		"default",             //For each workflow, returns information about whether this is the default workflow.
+	}
+
+	workflows, response, err := atlassian.Workflow.Gets(context.Background(), nil, expand, 0, 50)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+	}
+
+	for _, workflow := range workflows.Values {
+
+		log.Println("--------------------")
+		log.Printf("Workflow ID: %v", workflow.ID.EntityID)
+		log.Printf("Workflow Name: %v", workflow.ID.Name)
+		log.Printf("Workflow Description: %v", workflow.Description)
+
+		if workflow.Statuses != nil {
+			for index, status := range workflow.Statuses {
+				log.Printf("Workflow Status #%v - Name: %v - ID: %v", index+1, status.Name, status.ID)
+
+				if status.Properties != nil {
+					log.Printf("Workflow Status #%v - Property IssueEditable: %v", index+1, status.Properties.IssueEditable)
+				}
+
+			}
+		}
+
+		if workflow.Transitions != nil {
+
+			for index, transition := range workflow.Transitions {
+				log.Printf("Workflow Transition #%v - Name: %v - ID: %v - Type: %v - From: %v - To: %v",
+					index+1, transition.Name, transition.ID, transition.Type, transition.From, transition.To)
+
+				if transition.Rules != nil {
+
+					for index, condition := range transition.Rules.Conditions {
+						log.Printf("Workflow Transition #%v Condition - Type: %v", index+1, condition.Type)
+					}
+
+					for index, validator := range transition.Rules.Validators {
+						log.Printf("Workflow Transition #%v Validator - Type: %v", index+1, validator.Type)
+					}
+
+					for index, postFunction := range transition.Rules.PostFunctions {
+						log.Printf("Workflow Transition #%v PostFunction - Type: %v", index+1, postFunction.Type)
+					}
+				}
+			}
+		}
+
+		log.Println("--------------------")
+	}
+
+}
diff --git a/jira/examples/workflowScheme/create/create.go b/jira/examples/workflowScheme/create/create.go
new file mode 100644
index 0000000..cea9bf8
--- /dev/null
+++ b/jira/examples/workflowScheme/create/create.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	var payload = &jira.WorkflowSchemePayloadScheme{
+		DefaultWorkflow: "jira",
+		Name:            "Example workflow scheme",
+		Description:     "The description of the example workflow scheme.",
+		IssueTypeMappings: map[string]string{
+			"10000": "scrum workflow",
+			"10001": "builds workflow",
+		},
+	}
+
+	workflowScheme, response, err := atlassian.Workflow.Scheme.Create(context.Background(), payload)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+	}
+
+	log.Println(workflowScheme)
+}
diff --git a/jira/examples/workflowScheme/delete/delete.go b/jira/examples/workflowScheme/delete/delete.go
new file mode 100644
index 0000000..da4d2e1
--- /dev/null
+++ b/jira/examples/workflowScheme/delete/delete.go
@@ -0,0 +1,45 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	var workflowSchemeID = 10006
+
+	response, err := atlassian.Workflow.Scheme.Delete(context.Background(), workflowSchemeID)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+	}
+
+}
diff --git a/jira/examples/workflowScheme/get/get.go b/jira/examples/workflowScheme/get/get.go
new file mode 100644
index 0000000..b234e51
--- /dev/null
+++ b/jira/examples/workflowScheme/get/get.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	var (
+		workflowSchemeID    = 10006
+		returnDraftIfExists = false
+	)
+
+	workflowScheme, response, err := atlassian.Workflow.Scheme.Get(context.Background(), workflowSchemeID, returnDraftIfExists)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+	}
+
+	log.Println("------------")
+	log.Printf("Workflow Scheme ID: %v", workflowScheme.ID)
+	log.Printf("Workflow Scheme Name: %v", workflowScheme.Name)
+	log.Printf("Workflow Scheme Description: %v", workflowScheme.Description)
+	log.Printf("Workflow Scheme DefaultWorkflow: %v", workflowScheme.DefaultWorkflow)
+	log.Printf("Workflow Scheme Draft: %v", workflowScheme.Draft)
+	log.Println("------------")
+}
diff --git a/jira/examples/workflowScheme/gets/gets.go b/jira/examples/workflowScheme/gets/gets.go
new file mode 100644
index 0000000..06e7dc7
--- /dev/null
+++ b/jira/examples/workflowScheme/gets/gets.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	workflowsSchemes, response, err := atlassian.Workflow.Scheme.Gets(context.Background(), 0, 50)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+	}
+
+	for _, workflowScheme := range workflowsSchemes.Values {
+
+		log.Println("------------")
+		log.Printf("Workflow Scheme ID: %v", workflowScheme.ID)
+		log.Printf("Workflow Scheme Name: %v", workflowScheme.Name)
+		log.Printf("Workflow Scheme Description: %v", workflowScheme.Description)
+		log.Printf("Workflow Scheme DefaultWorkflow: %v", workflowScheme.DefaultWorkflow)
+		log.Printf("Workflow Scheme Draft: %v", workflowScheme.Draft)
+		log.Println("------------")
+	}
+
+}
diff --git a/jira/examples/workflowScheme/update/update.go b/jira/examples/workflowScheme/update/update.go
new file mode 100644
index 0000000..fddbb40
--- /dev/null
+++ b/jira/examples/workflowScheme/update/update.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/jira"
+	"log"
+	"os"
+)
+
+func main() {
+
+	/*
+		----------- Set an environment variable in git bash -----------
+		export HOST="https://ctreminiom.atlassian.net/"
+		export MAIL="MAIL_ADDRESS"
+		export TOKEN="TOKEN_API"
+
+		Docs: https://stackoverflow.com/questions/34169721/set-an-environment-variable-in-git-bash
+	*/
+
+	var (
+		host  = os.Getenv("HOST")
+		mail  = os.Getenv("MAIL")
+		token = os.Getenv("TOKEN")
+	)
+
+	atlassian, err := jira.New(nil, host)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	atlassian.Auth.SetBasicAuth(mail, token)
+
+	var (
+		payload = &jira.WorkflowSchemePayloadScheme{
+			DefaultWorkflow: "jira",
+			Name:            "Example workflow scheme - UPDATED",
+			Description:     "The description of the example workflow scheme. - UPDATED"}
+		workflowSchemeID = 10006
+	)
+
+	workflowScheme, response, err := atlassian.Workflow.Scheme.Update(context.Background(), workflowSchemeID, payload)
+	if err != nil {
+		if response != nil {
+			log.Println(response.Endpoint)
+			log.Println(response.Code)
+			log.Println(response.Bytes.String())
+		}
+		return
+	}
+
+	log.Println("------------")
+	log.Printf("Workflow Scheme ID: %v", workflowScheme.ID)
+	log.Printf("Workflow Scheme Name: %v", workflowScheme.Name)
+	log.Printf("Workflow Scheme Description: %v", workflowScheme.Description)
+	log.Printf("Workflow Scheme DefaultWorkflow: %v", workflowScheme.DefaultWorkflow)
+	log.Printf("Workflow Scheme Draft: %v", workflowScheme.Draft)
+	log.Println("------------")
+
+}
diff --git a/jira/jira.go b/jira/jira.go
index eca9266..03ebdcf 100644
--- a/jira/jira.go
+++ b/jira/jira.go
@@ -34,6 +34,7 @@ type Client struct {
 	Task       *TaskService
 	User       *UserService
 	MySelf     *MySelfService
+	Workflow   *WorkflowService
 
 	//Service Management Module
 	ServiceManagement *sm.Client
@@ -132,7 +133,7 @@ func New(httpClient *http.Client, site string) (client *Client, err error) {
 		Votes:    &VoteService{client: client},
 		Watchers: &WatcherService{client: client},
 		Label:    &LabelService{client: client},
-		Worklog: &IssueWorklogService{client: client},
+		Worklog:  &IssueWorklogService{client: client},
 	}
 
 	client.Permission = &PermissionService{
@@ -167,6 +168,11 @@ func New(httpClient *http.Client, site string) (client *Client, err error) {
 
 	client.MySelf = &MySelfService{client: client}
 
+	client.Workflow = &WorkflowService{
+		client: client,
+		Scheme: &WorkflowSchemeService{client: client},
+	}
+
 	return
 }
 
@@ -270,4 +276,4 @@ var (
 	urlParsedError          = "URL parsing failed: %v"
 	requestFailedError      = "request failed. Please analyze the request body for more details. Status Code: %d"
 	structureNotParsedError = errors.New("failed to parse the interface pointer, please provide a valid one")
-)
\ No newline at end of file
+)
diff --git a/jira/mocks/get-worflow-scheme.json b/jira/mocks/get-worflow-scheme.json
new file mode 100644
index 0000000..d9cf6d6
--- /dev/null
+++ b/jira/mocks/get-worflow-scheme.json
@@ -0,0 +1,51 @@
+{
+  "id": 30,
+  "name": "<string>",
+  "description": "<string>",
+  "defaultWorkflow": "<string>",
+  "issueTypeMappings": {},
+  "originalDefaultWorkflow": "<string>",
+  "originalIssueTypeMappings": {},
+  "draft": true,
+  "lastModifiedUser": {
+    "self": "<string>",
+    "key": "<string>",
+    "accountId": "<string>",
+    "accountType": "atlassian",
+    "name": "<string>",
+    "emailAddress": "<string>",
+    "avatarUrls": {
+      "16x16": "<string>",
+      "24x24": "<string>",
+      "32x32": "<string>",
+      "48x48": "<string>"
+    },
+    "displayName": "<string>",
+    "active": true,
+    "timeZone": "<string>",
+    "locale": "<string>",
+    "groups": {
+      "size": 2154,
+      "items": [
+        {}
+      ],
+      "pagingCallback": {},
+      "callback": {},
+      "max-results": 2154
+    },
+    "applicationRoles": {
+      "size": 2154,
+      "items": [
+        {}
+      ],
+      "pagingCallback": {},
+      "callback": {},
+      "max-results": 2154
+    },
+    "expand": "<string>"
+  },
+  "lastModified": "<string>",
+  "self": "<string>",
+  "updateDraftIfNeeded": true,
+  "issueTypes": {}
+}
\ No newline at end of file
diff --git a/jira/mocks/get-workflow-schemes.json b/jira/mocks/get-workflow-schemes.json
new file mode 100644
index 0000000..943b1fe
--- /dev/null
+++ b/jira/mocks/get-workflow-schemes.json
@@ -0,0 +1,40 @@
+{
+  "self": "<string>",
+  "nextPage": "<string>",
+  "maxResults": 51,
+  "startAt": 37,
+  "total": 29,
+  "isLast": true,
+  "values": [
+    {
+      "id": 30,
+      "name": "<string>",
+      "description": "<string>",
+      "defaultWorkflow": "<string>",
+      "issueTypeMappings": {},
+      "originalDefaultWorkflow": "<string>",
+      "originalIssueTypeMappings": {},
+      "draft": true,
+      "lastModifiedUser": {
+        "self": "<string>",
+        "key": "<string>",
+        "accountId": "<string>",
+        "accountType": "atlassian",
+        "name": "<string>",
+        "emailAddress": "<string>",
+        "avatarUrls": {},
+        "displayName": "<string>",
+        "active": true,
+        "timeZone": "<string>",
+        "locale": "<string>",
+        "groups": {},
+        "applicationRoles": {},
+        "expand": "<string>"
+      },
+      "lastModified": "<string>",
+      "self": "<string>",
+      "updateDraftIfNeeded": true,
+      "issueTypes": {}
+    }
+  ]
+}
\ No newline at end of file
diff --git a/jira/mocks/get-workflows.json b/jira/mocks/get-workflows.json
new file mode 100644
index 0000000..b37a3ba
--- /dev/null
+++ b/jira/mocks/get-workflows.json
@@ -0,0 +1,43 @@
+{
+  "self": "<string>",
+  "nextPage": "<string>",
+  "maxResults": 51,
+  "startAt": 37,
+  "total": 29,
+  "isLast": true,
+  "values": [
+    {
+      "id": {
+        "name": "<string>",
+        "entityId": "<string>"
+      },
+      "description": "<string>",
+      "transitions": [
+        {
+          "id": "<string>",
+          "name": "<string>",
+          "description": "<string>",
+          "from": [
+            "<string>"
+          ],
+          "to": "<string>",
+          "type": "global",
+          "screen": {
+            "id": "<string>"
+          },
+          "rules": {}
+        }
+      ],
+      "statuses": [
+        {
+          "id": "<string>",
+          "name": "<string>",
+          "properties": {
+            "issueEditable": true
+          }
+        }
+      ],
+      "isDefault": true
+    }
+  ]
+}
\ No newline at end of file
diff --git a/jira/workflow.go b/jira/workflow.go
new file mode 100644
index 0000000..bd350ff
--- /dev/null
+++ b/jira/workflow.go
@@ -0,0 +1,144 @@
+package jira
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+type WorkflowService struct {
+	client *Client
+	Scheme *WorkflowSchemeService
+}
+
+// Gets returns a paginated list of published classic workflows.
+// When workflow names are specified, details of those workflows are returned.
+// Otherwise, all published classic workflows are returned.
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-search-get
+func (w *WorkflowService) Gets(ctx context.Context, workflowNames, expand []string, startAt, maxResults int) (result *WorkflowPageScheme,
+	response *ResponseScheme, err error) {
+
+	params := url.Values{}
+	params.Add("startAt", strconv.Itoa(startAt))
+	params.Add("maxResults", strconv.Itoa(maxResults))
+
+	for _, workflowName := range workflowNames {
+		params.Add("workflowName", workflowName)
+	}
+
+	if len(expand) != 0 {
+		params.Add("expand", strings.Join(expand, ","))
+	}
+
+	var endpoint = fmt.Sprintf("/rest/api/3/workflow/search?%v", params.Encode())
+
+	request, err := w.client.newRequest(ctx, http.MethodGet, endpoint, nil)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+
+	response, err = w.client.call(request, &result)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// Delete deletes a workflow.
+//
+// The workflow cannot be deleted if it is:
+//
+//    an active workflow.
+//    a system workflow.
+//    associated with any workflow scheme.
+//    associated with any draft workflow scheme.
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-entityid-delete
+// NOTE: Experimental Method
+func (w *WorkflowService) Delete(ctx context.Context, workflowID string) (response *ResponseScheme, err error) {
+
+	if len(workflowID) == 0 {
+		return nil, notWorkflowIDError
+	}
+
+	var endpoint = fmt.Sprintf("/rest/api/3/workflow/%v", workflowID)
+
+	request, err := w.client.newRequest(ctx, http.MethodDelete, endpoint, nil)
+	if err != nil {
+		return
+	}
+
+	response, err = w.client.call(request, nil)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+type WorkflowPageScheme struct {
+	Self       string            `json:"self,omitempty"`
+	NextPage   string            `json:"nextPage,omitempty"`
+	MaxResults int               `json:"maxResults,omitempty"`
+	StartAt    int               `json:"startAt,omitempty"`
+	Total      int               `json:"total,omitempty"`
+	IsLast     bool              `json:"isLast,omitempty"`
+	Values     []*WorkflowScheme `json:"values,omitempty"`
+}
+
+type WorkflowScheme struct {
+	ID          *WorkflowPublishedIDScheme  `json:"id,omitempty"`
+	Transitions []*WorkflowTransitionScheme `json:"transitions,omitempty"`
+	Statuses    []*WorkflowStatusScheme     `json:"statuses,omitempty"`
+	Description string                      `json:"description,omitempty"`
+	IsDefault   bool                        `json:"isDefault,omitempty"`
+}
+
+type WorkflowPublishedIDScheme struct {
+	Name     string `json:"name,omitempty"`
+	EntityID string `json:"entityId,omitempty"`
+}
+
+type WorkflowTransitionScheme struct {
+	ID          string                          `json:"id,omitempty"`
+	Name        string                          `json:"name,omitempty"`
+	Description string                          `json:"description,omitempty"`
+	From        []string                        `json:"from,omitempty"`
+	To          string                          `json:"to,omitempty"`
+	Type        string                          `json:"type,omitempty"`
+	Screen      *WorkflowTransitionScreenScheme `json:"screen,omitempty"`
+	Rules       *WorkflowTransitionRulesScheme  `json:"rules,omitempty"`
+}
+
+type WorkflowTransitionScreenScheme struct {
+	ID string `json:"id,omitempty"`
+}
+
+type WorkflowTransitionRulesScheme struct {
+	Conditions    []*WorkflowTransitionRuleScheme `json:"conditions,omitempty"`
+	Validators    []*WorkflowTransitionRuleScheme `json:"validators,omitempty"`
+	PostFunctions []*WorkflowTransitionRuleScheme `json:"postFunctions,omitempty"`
+}
+
+type WorkflowTransitionRuleScheme struct {
+	Type string `json:"type"`
+}
+
+type WorkflowStatusScheme struct {
+	ID         string                          `json:"id"`
+	Name       string                          `json:"name"`
+	Properties *WorkflowStatusPropertiesScheme `json:"properties"`
+}
+
+type WorkflowStatusPropertiesScheme struct {
+	IssueEditable bool `json:"issueEditable"`
+}
+
+var (
+	notWorkflowIDError = fmt.Errorf("error!, please provide a valid entity ID of the workflow")
+)
diff --git a/jira/workflowScheme.go b/jira/workflowScheme.go
new file mode 100644
index 0000000..75ce0ef
--- /dev/null
+++ b/jira/workflowScheme.go
@@ -0,0 +1,177 @@
+package jira
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+type WorkflowSchemeService struct{ client *Client }
+
+// Gets returns a paginated list of all workflow schemes, not including draft workflow schemes.
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-schemes/#api-rest-api-3-workflowscheme-get
+func (w *WorkflowSchemeService) Gets(ctx context.Context, startAt, maxResults int) (result *WorkflowSchemePageScheme,
+	response *ResponseScheme, err error) {
+
+	params := url.Values{}
+	params.Add("startAt", strconv.Itoa(startAt))
+	params.Add("maxResults", strconv.Itoa(maxResults))
+
+	var endpoint = fmt.Sprintf("/rest/api/3/workflowscheme?%v", params.Encode())
+
+	request, err := w.client.newRequest(ctx, http.MethodGet, endpoint, nil)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+
+	response, err = w.client.call(request, &result)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// Create creates a workflow scheme.
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-schemes/#api-rest-api-3-workflowscheme-post
+func (w *WorkflowSchemeService) Create(ctx context.Context, payload *WorkflowSchemePayloadScheme) (result *WorkflowSchemeScheme,
+	response *ResponseScheme, err error) {
+
+	var endpoint = "/rest/api/3/workflowscheme"
+
+	payloadAsReader, err := transformStructToReader(payload)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	request, err := w.client.newRequest(ctx, http.MethodPost, endpoint, payloadAsReader)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+	request.Header.Set("Content-Type", "application/json")
+
+	response, err = w.client.call(request, &result)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// Get returns a workflow scheme.
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-schemes/#api-rest-api-3-workflowscheme-id-get
+func (w *WorkflowSchemeService) Get(ctx context.Context, workflowSchemeID int, isExits bool) (result *WorkflowSchemeScheme,
+	response *ResponseScheme, err error) {
+
+	var endpoint strings.Builder
+	endpoint.WriteString(fmt.Sprintf("/rest/api/3/workflowscheme/%v", workflowSchemeID))
+
+	query := url.Values{}
+	if isExits {
+		query.Add("returnDraftIfExists", "true")
+	}
+
+	if query.Encode() != "" {
+		endpoint.WriteString(fmt.Sprintf("?%v", query.Encode()))
+	}
+
+	request, err := w.client.newRequest(ctx, http.MethodGet, endpoint.String(), nil)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+
+	response, err = w.client.call(request, &result)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// Update updates a workflow scheme, including the name, default workflow, issue type to project mappings,
+// and more. If the workflow scheme is active (that is, being used by at least one project),
+// then a draft workflow scheme is created or updated instead, provided that updateDraftIfNeeded is set to true.
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-schemes/#api-rest-api-3-workflowscheme-id-put
+func (w *WorkflowSchemeService) Update(ctx context.Context, workflowSchemeID int, payload *WorkflowSchemePayloadScheme) (result *WorkflowSchemeScheme,
+	response *ResponseScheme, err error) {
+
+	var endpoint = fmt.Sprintf("/rest/api/3/workflowscheme/%v", workflowSchemeID)
+
+	payloadAsReader, err := transformStructToReader(payload)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	request, err := w.client.newRequest(ctx, http.MethodPut, endpoint, payloadAsReader)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+	request.Header.Set("Content-Type", "application/json")
+
+	response, err = w.client.call(request, &result)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// Delete deletes a workflow scheme.
+// Note that a workflow scheme cannot be deleted if it is active (that is, being used by at least one project).
+// Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-schemes/#api-rest-api-3-workflowscheme-id-delete
+func (w *WorkflowSchemeService) Delete(ctx context.Context, workflowSchemeID int) (response *ResponseScheme, err error) {
+
+	var endpoint = fmt.Sprintf("/rest/api/3/workflowscheme/%v", workflowSchemeID)
+
+	request, err := w.client.newRequest(ctx, http.MethodDelete, endpoint, nil)
+	if err != nil {
+		return
+	}
+
+	response, err = w.client.call(request, nil)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+type WorkflowSchemePayloadScheme struct {
+	DefaultWorkflow   string      `json:"defaultWorkflow,omitempty"`
+	Name              string      `json:"name,omitempty"`
+	Description       string      `json:"description,omitempty"`
+	IssueTypeMappings interface{} `json:"issueTypeMappings,omitempty"`
+}
+
+type WorkflowSchemePageScheme struct {
+	Self       string                  `json:"self,omitempty"`
+	NextPage   string                  `json:"nextPage,omitempty"`
+	MaxResults int                     `json:"maxResults,omitempty"`
+	StartAt    int                     `json:"startAt,omitempty"`
+	Total      int                     `json:"total,omitempty"`
+	IsLast     bool                    `json:"isLast,omitempty"`
+	Values     []*WorkflowSchemeScheme `json:"values,omitempty"`
+}
+
+type WorkflowSchemeScheme struct {
+	ID                  int         `json:"id,omitempty"`
+	Name                string      `json:"name,omitempty"`
+	Description         string      `json:"description,omitempty"`
+	DefaultWorkflow     string      `json:"defaultWorkflow,omitempty"`
+	Draft               bool        `json:"draft,omitempty"`
+	LastModifiedUser    *UserScheme `json:"lastModifiedUser,omitempty"`
+	LastModified        string      `json:"lastModified,omitempty"`
+	Self                string      `json:"self,omitempty"`
+	UpdateDraftIfNeeded bool        `json:"updateDraftIfNeeded,omitempty"`
+}


Test patch:
diff --git a/jira/workflowScheme_test.go b/jira/workflowScheme_test.go
new file mode 100644
index 0000000..a3106f6
--- /dev/null
+++ b/jira/workflowScheme_test.go
@@ -0,0 +1,755 @@
+package jira
+
+import (
+	"context"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"net/http"
+	"net/url"
+	"testing"
+)
+
+func TestWorkflowSchemeService_Create(t *testing.T) {
+
+	testCases := []struct {
+		name               string
+		payload            *WorkflowSchemePayloadScheme
+		mockFile           string
+		wantHTTPMethod     string
+		endpoint           string
+		context            context.Context
+		wantHTTPCodeReturn int
+		wantErr            bool
+	}{
+		{
+			name:     "CreateWorkflowSchemeWhenTheParametersAreCorrect",
+			mockFile: "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPost,
+			endpoint:           "/rest/api/3/workflowscheme",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "CreateWorkflowSchemeWhenThePayloadIsNotSet",
+			mockFile:           "./mocks/get-worflow-scheme.json",
+			payload:            nil,
+			wantHTTPMethod:     http.MethodPost,
+			endpoint:           "/rest/api/3/workflowscheme",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:     "CreateWorkflowSchemeWhenTheContextIsNotSet",
+			mockFile: "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPost,
+			endpoint:           "/rest/api/3/workflowscheme",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:     "CreateWorkflowSchemeWhenTheRequestMethodIsIncorrect",
+			mockFile: "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/api/3/workflowscheme",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:     "CreateWorkflowSchemeWhenTheStatusCodeIsIncorrect",
+			mockFile: "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPost,
+			endpoint:           "/rest/api/3/workflowscheme",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowSchemeService{client: mockClient}
+
+			gotResult, gotResponse, err := i.Create(testCase.context, testCase.payload)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}
+
+func TestWorkflowSchemeService_Get(t *testing.T) {
+
+	testCases := []struct {
+		name               string
+		workflowSchemeID   int
+		isExits            bool
+		mockFile           string
+		wantHTTPMethod     string
+		endpoint           string
+		context            context.Context
+		wantHTTPCodeReturn int
+		wantErr            bool
+	}{
+		{
+			name:               "GetWorkflowWorkflowSchemeWhenTheParametersAreCorrect",
+			workflowSchemeID:   1006,
+			isExits:            true,
+			mockFile:           "./mocks/get-worflow-scheme.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme/1006?returnDraftIfExists=true",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetWorkflowWorkflowSchemeWhenTheContextIsNotSet",
+			workflowSchemeID:   1006,
+			isExits:            true,
+			mockFile:           "./mocks/get-worflow-scheme.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme/1006?returnDraftIfExists=true",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetWorkflowWorkflowSchemeWhenTheRequestMethodIsIncorrect",
+			workflowSchemeID:   1006,
+			isExits:            true,
+			mockFile:           "./mocks/get-worflow-scheme.json",
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/api/3/workflowscheme/1006?returnDraftIfExists=true",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetWorkflowWorkflowSchemeWhenTheStatusCodeIsIncorrect",
+			workflowSchemeID:   1006,
+			isExits:            true,
+			mockFile:           "./mocks/get-worflow-scheme.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme/1006?returnDraftIfExists=true",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetWorkflowWorkflowSchemeWhenTheResponseBodyIsEmpty",
+			workflowSchemeID:   1006,
+			isExits:            true,
+			mockFile:           "./mocks/empty_json.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme/1006?returnDraftIfExists=true",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowSchemeService{client: mockClient}
+
+			gotResult, gotResponse, err := i.Get(testCase.context, testCase.workflowSchemeID, testCase.isExits)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}
+
+func TestWorkflowSchemeService_Update(t *testing.T) {
+
+	testCases := []struct {
+		name               string
+		workflowSchemeID   int
+		payload            *WorkflowSchemePayloadScheme
+		mockFile           string
+		wantHTTPMethod     string
+		endpoint           string
+		context            context.Context
+		wantHTTPCodeReturn int
+		wantErr            bool
+	}{
+		{
+			name:             "UpdateWorkflowSchemeWhenTheParametersAreCorrect",
+			workflowSchemeID: 1006,
+			mockFile:         "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPut,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:             "UpdateWorkflowSchemeWhenTheContextIsNotSet",
+			workflowSchemeID: 1006,
+			mockFile:         "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPut,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:             "UpdateWorkflowSchemeWhenTheResponseBodyIsEmpty",
+			workflowSchemeID: 1006,
+			mockFile:         "./mocks/empty_json.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPut,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:             "UpdateWorkflowSchemeWhenTheRequestMethodIsIncorrect",
+			workflowSchemeID: 1006,
+			mockFile:         "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:             "UpdateWorkflowSchemeWhenTheStatusCodeIsIncorrect",
+			workflowSchemeID: 1006,
+			mockFile:         "./mocks/get-worflow-scheme.json",
+			payload: &WorkflowSchemePayloadScheme{
+				DefaultWorkflow: "jira",
+				Name:            "Example workflow scheme",
+				Description:     "The description of the example workflow scheme.",
+				IssueTypeMappings: map[string]string{
+					"10000": "scrum workflow",
+					"10001": "builds workflow",
+				},
+			},
+			wantHTTPMethod:     http.MethodPut,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+
+		{
+			name:               "UpdateWorkflowSchemeWhenThePayloadIsNotSet",
+			workflowSchemeID:   1006,
+			mockFile:           "./mocks/get-worflow-scheme.json",
+			payload:            nil,
+			wantHTTPMethod:     http.MethodPut,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowSchemeService{client: mockClient}
+
+			gotResult, gotResponse, err := i.Update(testCase.context, testCase.workflowSchemeID, testCase.payload)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}
+
+func TestWorkflowSchemeService_Gets(t *testing.T) {
+
+	testCases := []struct {
+		name                string
+		startAt, maxResults int
+		mockFile            string
+		wantHTTPMethod      string
+		endpoint            string
+		context             context.Context
+		wantHTTPCodeReturn  int
+		wantErr             bool
+	}{
+		{
+			name:               "GetWorkflowSchemesWhenTheParametersAreCorrect",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflow-schemes.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme?maxResults=50&startAt=0",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetWorkflowSchemesWhenTheRequestMethodIsIncorrect",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflow-schemes.json",
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/api/3/workflowscheme?maxResults=50&startAt=0",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetWorkflowSchemesWhenTheStatusCodeIsIncorrect",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflow-schemes.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme?maxResults=50&startAt=0",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetWorkflowSchemesWhenTheContextIsNotSet",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflow-schemes.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme?maxResults=50&startAt=0",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetWorkflowSchemesWhenTheResponseBodyIsEmpty",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/empty_json.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme?maxResults=50&startAt=0",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowSchemeService{client: mockClient}
+
+			gotResult, gotResponse, err := i.Gets(testCase.context, testCase.startAt, testCase.maxResults)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}
+
+func TestWorkflowSchemeService_Delete(t *testing.T) {
+
+	testCases := []struct {
+		name               string
+		workflowSchemeID   int
+		mockFile           string
+		wantHTTPMethod     string
+		endpoint           string
+		context            context.Context
+		wantHTTPCodeReturn int
+		wantErr            bool
+	}{
+		{
+			name:               "DeleteWorkflowSchemeWhenTheParametersAreCorrect",
+			workflowSchemeID:   1006,
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            false,
+		},
+
+		{
+			name:               "DeleteWorkflowSchemeWhenTheRequestMethodIsIncorrect",
+			workflowSchemeID:   1006,
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            true,
+		},
+
+		{
+			name:               "DeleteWorkflowSchemeWhenTheStatusCodeIsIncorrect",
+			workflowSchemeID:   1006,
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+
+		{
+			name:               "DeleteWorkflowSchemeWhenTheContextIsNotSet",
+			workflowSchemeID:   1006,
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflowscheme/1006",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowSchemeService{client: mockClient}
+
+			gotResponse, err := i.Delete(testCase.context, testCase.workflowSchemeID)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}
diff --git a/jira/workflow_test.go b/jira/workflow_test.go
new file mode 100644
index 0000000..90b5f6a
--- /dev/null
+++ b/jira/workflow_test.go
@@ -0,0 +1,314 @@
+package jira
+
+import (
+	"context"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"net/http"
+	"net/url"
+	"testing"
+)
+
+func TestWorkflowService_Delete(t *testing.T) {
+
+	testCases := []struct {
+		name               string
+		workflowID         string
+		mockFile           string
+		wantHTTPMethod     string
+		endpoint           string
+		context            context.Context
+		wantHTTPCodeReturn int
+		wantErr            bool
+	}{
+		{
+			name:               "DeleteWorkflowWhenTheParametersAreCorrect",
+			workflowID:         "as49949ja-asjdasjd94-jasdjasjd",
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflow/as49949ja-asjdasjd94-jasdjasjd",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            false,
+		},
+
+		{
+			name:               "DeleteWorkflowWhenTheWorkflowIDIsNotSet",
+			workflowID:         "",
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflow/as49949ja-asjdasjd94-jasdjasjd",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            true,
+		},
+
+		{
+			name:               "DeleteWorkflowWhenTheContextIsNotSet",
+			workflowID:         "as49949ja-asjdasjd94-jasdjasjd",
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflow/as49949ja-asjdasjd94-jasdjasjd",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            true,
+		},
+
+		{
+			name:               "DeleteWorkflowWhenTheRequestMethodIsIncorrect",
+			workflowID:         "as49949ja-asjdasjd94-jasdjasjd",
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/api/3/workflow/as49949ja-asjdasjd94-jasdjasjd",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusNoContent,
+			wantErr:            true,
+		},
+
+		{
+			name:               "DeleteWorkflowWhenTheStatusCodeIsIncorrect",
+			workflowID:         "as49949ja-asjdasjd94-jasdjasjd",
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/3/workflow/as49949ja-asjdasjd94-jasdjasjd",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowService{client: mockClient}
+
+			gotResponse, err := i.Delete(testCase.context, testCase.workflowID)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}
+
+func TestWorkflowService_Gets(t *testing.T) {
+
+	testCases := []struct {
+		name                  string
+		startAt, maxResults   int
+		mockFile              string
+		workflowNames, expand []string
+		wantHTTPMethod        string
+		endpoint              string
+		context               context.Context
+		wantHTTPCodeReturn    int
+		wantErr               bool
+	}{
+		{
+			name:               "GetsWorkflowsWheTheParametersAreCorrect",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflows.json",
+			workflowNames:      []string{"workflow name 1", "workflow name 2"},
+			expand:             []string{"transitions", "transitions.rules", "default"},
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflow/search?expand=transitions%2Ctransitions.rules%2Cdefault&maxResults=50&startAt=0&workflowName=workflow+name+1&workflowName=workflow+name+2",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetsWorkflowsWheTheContextIsNotSet",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflows.json",
+			workflowNames:      []string{"workflow name 1", "workflow name 2"},
+			expand:             []string{"transitions", "transitions.rules", "default"},
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflow/search?expand=transitions%2Ctransitions.rules%2Cdefault&maxResults=50&startAt=0&workflowName=workflow+name+1&workflowName=workflow+name+2",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetsWorkflowsWheTheRequestMethodIsIncorrect",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflows.json",
+			workflowNames:      []string{"workflow name 1", "workflow name 2"},
+			expand:             []string{"transitions", "transitions.rules", "default"},
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/api/3/workflow/search?expand=transitions%2Ctransitions.rules%2Cdefault&maxResults=50&startAt=0&workflowName=workflow+name+1&workflowName=workflow+name+2",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetsWorkflowsWheTheStatusCodeIsIncorrect",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflows.json",
+			workflowNames:      []string{"workflow name 1", "workflow name 2"},
+			expand:             []string{"transitions", "transitions.rules", "default"},
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflow/search?expand=transitions%2Ctransitions.rules%2Cdefault&maxResults=50&startAt=0&workflowName=workflow+name+1&workflowName=workflow+name+2",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetsWorkflowsWheTheExpandsAreNotSet",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflows.json",
+			workflowNames:      []string{"workflow name 1", "workflow name 2"},
+			expand:             nil,
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflow/search?maxResults=50&startAt=0&workflowName=workflow+name+1&workflowName=workflow+name+2",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetsWorkflowsWheTheWorkflowNamesAreNotSet",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-workflows.json",
+			workflowNames:      nil,
+			expand:             []string{"transitions", "transitions.rules", "default"},
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflow/search?expand=transitions%2Ctransitions.rules%2Cdefault&maxResults=50&startAt=0",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetsWorkflowsWheTheResponseBodyIsEmpty",
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/empty_json.json",
+			workflowNames:      []string{"workflow name 1", "workflow name 2"},
+			expand:             []string{"transitions", "transitions.rules", "default"},
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/3/workflow/search?expand=transitions%2Ctransitions.rules%2Cdefault&maxResults=50&startAt=0&workflowName=workflow+name+1&workflowName=workflow+name+2",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			i := &WorkflowService{client: mockClient}
+
+			gotResult, gotResponse, err := i.Gets(testCase.context, testCase.workflowNames, testCase.expand,
+				testCase.startAt,
+				testCase.maxResults)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+			}
+		})
+
+	}
+
+}