Repository: VictorAvelar/mollie-api-go (go)

Issue:
Include new Gift card issuers
**Is your feature request related to a problem? Please describe.**
New gift cards issuer had been enabled by Mollie, it will be good if we include support to have full compatibility.

## ⚠️  Update - 03-10-2020
Main focus of this ticket should change towards the enable and disable gift card issuers in Profiles API
- [Enable gift card issuer for profile](https://docs.mollie.com/reference/v2/profiles-api/enable-gift-card-issuer)
- [Disable gift card issuer for profile](https://docs.mollie.com/reference/v2/profiles-api/disable-gift-card-issuer)

### August
- Thursday, 20th: Added `good4fun` as gift card issuer.
- Monday, 10th: Added `decadeaukaart` as gift card issuer.


### April 2020
- Friday, 3rd:
   - Added `restaurantcadeau` as gift card issuer.
   - Added `dinercadeau` as gift card issuer.

**Describe the solution you'd like**
The afore mentioned issuers are included as gift card issuer constants.


Pull request:
Feature/gift card toggle and supported issuers
<!--- Provide a general summary of your changes in the Title above -->

## Description

Adds types and methods to enable/disable gift card issuers from a profile.

## Motivation and context

Why is this change required? What problem does it solve?

Fixes #58 


Unblocks #83 

## How has this been tested?

Please describe in detail how you tested your changes.

go version 1.15.2 [dockerized and local]
macOS 10.15.6

## Types of changes

What types of changes does your code introduce? Put an `x` in all the boxes that apply:
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

Go over all the following points, and put an `x` in all the boxes that apply.

Please, please, please, don't send your pull request until all of the boxes are ticked. Once your pull request is created, it will trigger a build on our continuous integration server to make sure your [tests and code style pass](https://help.github.com/articles/about-required-status-checks/).

- [x] I have read the **[CONTRIBUTING](CONTRIBUTING.md)** document.
- [x] My pull request addresses exactly one patch/feature.
- [x] I have created a branch for this patch/feature.
- [x] Each individual commit in the pull request is meaningful.
- [x] I have added tests to cover my changes.
- [x] If my change requires a change to the documentation, I have updated it accordingly.

If you're unsure about any of these, don't hesitate to ask. We're here to help!


Patch:
diff --git a/.github/stale.yml b/.github/stale.yml
index 59af9f0..1783fcf 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -1,7 +1,7 @@
 # Number of days of inactivity before an issue becomes stale
-daysUntilStale: 10
+daysUntilStale: 5
 # Number of days of inactivity before a stale issue is closed
-daysUntilClose: 5
+daysUntilClose: 10
 # Issues with these labels will never be considered stale
 exemptLabels:
   - pinned
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index e789960..a71488d 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -8,7 +8,7 @@ jobs:
   golangci:
     strategy:
       matrix:
-        go-version: [1.14.x, 1.15.x]
+        go-version: [1.15.x]
     name: Linter
     runs-on: ubuntu-latest
     steps:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94545f4..eec085c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
 - Dockerfile for test execution #81
 - Makefile with used commands #81
 - Code samples for profiles #82
+- Methods for enabling/disabling payment methods #84
 
 ## Fixed
 - golint style errors in `mandates.go` #80
diff --git a/mollie/gift_cards.go b/mollie/gift_cards.go
new file mode 100644
index 0000000..45443dd
--- /dev/null
+++ b/mollie/gift_cards.go
@@ -0,0 +1,59 @@
+package mollie
+
+// GiftCardIssuer type describes issuers supported
+// by mollie.
+type GiftCardIssuer string
+
+// sportenfitcadeau, sustainablefashion, travelcheq, vvvgiftcard, vvvdinercheque,
+// vvvlekkerweg, webshopgiftcard, yourgift
+
+// Supported gift card issuers
+const (
+	DecaudeuKaart              GiftCardIssuer = "decadeaukaart"
+	Dinercadeau                GiftCardIssuer = "dinercadeau"
+	Fashioncheque              GiftCardIssuer = "fashioncheque"
+	Festivalcadeau             GiftCardIssuer = "festivalcadeau"
+	Good4fun                   GiftCardIssuer = "good4fun"
+	Kunstencultuurcadeaukaart  GiftCardIssuer = "kunstencultuurcadeaukaart"
+	Nationalebioscoopbon       GiftCardIssuer = "nationalebioscoopbon"
+	Nationaleentertainmentcard GiftCardIssuer = "nationaleentertainmentcard"
+	Nationalegolfbon           GiftCardIssuer = "nationalegolfbon"
+	Ohmygood                   GiftCardIssuer = "ohmygood"
+	Podiumcadeaukaart          GiftCardIssuer = "podiumcadeaukaart"
+	Reiscadeau                 GiftCardIssuer = "reiscadeau"
+	Restaurantcadeau           GiftCardIssuer = "restaurantcadeau"
+	Sportenfitcadeau           GiftCardIssuer = "sportenfitcadeau"
+	Sustainablefashion         GiftCardIssuer = "sustainablefashion"
+	Travelcheq                 GiftCardIssuer = "travelcheq"
+	Vvvgiftcard                GiftCardIssuer = "vvvgiftcard"
+	Vvvdinercheque             GiftCardIssuer = "vvvdinercheque"
+	Vvvlekkerweg               GiftCardIssuer = "vvvlekkerweg"
+	Webshopgiftcard            GiftCardIssuer = "webshopgiftcard"
+	Yourgift                   GiftCardIssuer = "yourgift"
+)
+
+// GiftCardIssuerStatus describes the status of a gift
+// card issuer in your account.
+type GiftCardIssuerStatus string
+
+// Valid issuer statuses
+const (
+	PendingIssuer GiftCardIssuerStatus = "pending-issuer"
+	EnabledIssuer GiftCardIssuerStatus = "enabled"
+)
+
+// GiftCardEnabled describes the response of a gift card
+// issuer enable operation.
+type GiftCardEnabled struct {
+	Resource    string               `json:"resource,omitempty"`
+	ID          GiftCardIssuer       `json:"id,omitempty"`
+	Description string               `json:"description,omitempty"`
+	Status      GiftCardIssuerStatus `json:"status,omitempty"`
+	Links       GiftCardLinks        `json:"_links,omitempty"`
+}
+
+// GiftCardLinks are links embeded when a gift card is enabled.
+type GiftCardLinks struct {
+	Self          URL `json:"self,omitempty"`
+	Documentation URL `json:"documentation,omitempty"`
+}
diff --git a/mollie/profiles.go b/mollie/profiles.go
index 5f87f4d..85d8322 100644
--- a/mollie/profiles.go
+++ b/mollie/profiles.go
@@ -196,3 +196,73 @@ func (ps *ProfilesService) DisablePaymentMethod(id string, pm PaymentMethod) (er
 	}
 	return
 }
+
+// EnableGiftCardIssuer activates the requested giftcard issuer for the provided
+// profile id.
+//
+// See: https://docs.mollie.com/reference/v2/profiles-api/enable-gift-card-issuer
+func (ps *ProfilesService) EnableGiftCardIssuer(profileID string, issuer GiftCardIssuer) (gc *GiftCardEnabled, err error) {
+	res, err := ps.toggleGiftCardIssuerStatus(profileID, http.MethodPost, issuer)
+	if err != nil {
+		return
+	}
+
+	if err = json.Unmarshal(res.content, &gc); err != nil {
+		return
+	}
+	return
+}
+
+// DisableGiftCardIssuer deactivates the requested giftcard issuer for the provided
+// profile id.
+//
+// See: https://docs.mollie.com/reference/v2/profiles-api/disable-gift-card-issuer
+func (ps *ProfilesService) DisableGiftCardIssuer(profileID string, issuer GiftCardIssuer) (err error) {
+	_, err = ps.toggleGiftCardIssuerStatus(profileID, http.MethodDelete, issuer)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// EnableGiftCardIssuerForCurrent activates the specified issuer for the
+// curent profile (token owner).
+//
+// See: https://docs.mollie.com/reference/v2/profiles-api/enable-gift-card-issuer
+func (ps *ProfilesService) EnableGiftCardIssuerForCurrent(issuer GiftCardIssuer) (gc *GiftCardEnabled, err error) {
+	res, err := ps.toggleGiftCardIssuerStatus("me", http.MethodPost, issuer)
+	if err != nil {
+		return
+	}
+
+	if err = json.Unmarshal(res.content, &gc); err != nil {
+		return
+	}
+	return
+}
+
+// DisableGiftCardIssuerForCurrent deactivates the specified issuer for the
+// curent profile (token owner).
+//
+// See: https://docs.mollie.com/reference/v2/profiles-api/disable-gift-card-issuer
+func (ps *ProfilesService) DisableGiftCardIssuerForCurrent(issuer GiftCardIssuer) (err error) {
+	_, err = ps.toggleGiftCardIssuerStatus("me", http.MethodDelete, issuer)
+	if err != nil {
+		return
+	}
+	return
+}
+
+func (ps *ProfilesService) toggleGiftCardIssuerStatus(profileID string, method string, issuer GiftCardIssuer) (r *Response, err error) {
+	u := fmt.Sprintf("v2/profiles/%s/methods/giftcard/issuers/%s", profileID, issuer)
+	req, err := ps.client.NewAPIRequest(method, u, nil)
+	if err != nil {
+		return
+	}
+
+	r, err = ps.client.Do(req)
+	if err != nil {
+		return
+	}
+	return
+}


Test patch:
diff --git a/mollie/profiles_test.go b/mollie/profiles_test.go
index 20868c6..566a68c 100644
--- a/mollie/profiles_test.go
+++ b/mollie/profiles_test.go
@@ -42,7 +42,7 @@ func TestProfilesService_Get(t *testing.T) {
 func ExampleProfilesService_Get() {
 	setup()
 	defer teardown()
-	id := "pfl_v9hTwCvYqw" 
+	id := "pfl_v9hTwCvYqw"
 
 	_ = tClient.WithAuthenticationValue("test_token")
 
@@ -55,13 +55,12 @@ func ExampleProfilesService_Get() {
 		_, _ = w.Write([]byte(testdata.GetProfileResponse))
 	})
 
-
 	p, err := tClient.Profiles.Get(id)
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	fmt.Println(p.ID) 
+	fmt.Println(p.ID)
 	//Output: pfl_v9hTwCvYqw
 }
 
@@ -270,6 +269,136 @@ func TestProfilesService_DisablePaymentMethod(t *testing.T) {
 	}
 }
 
+func TestProfilesService_EnableGiftCardIssuer(t *testing.T) {
+	setEnv()
+	setup()
+	defer func() {
+		teardown()
+		unsetEnv()
+	}()
+
+	id := "pfl_v9hTwCvYqw"
+
+	tMux.HandleFunc(
+		fmt.Sprintf("/v2/profiles/%s/methods/giftcard/issuers/%s", id, Festivalcadeau),
+		func(rw http.ResponseWriter, r *http.Request) {
+			testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
+			testMethod(t, r, "POST")
+			if _, ok := r.Header[AuthHeader]; !ok {
+				rw.WriteHeader(http.StatusUnauthorized)
+			}
+
+			rw.WriteHeader(http.StatusOK)
+			_, _ = rw.Write([]byte(testdata.EnableGiftCardIssuerResponse))
+		},
+	)
+
+	res, err := tClient.Profiles.EnableGiftCardIssuer(id, Festivalcadeau)
+
+	if err != nil {
+		t.Error(err)
+	}
+
+	if res.ID != Festivalcadeau {
+		t.Errorf("unexpected id received: want %v, got %v", Festivalcadeau, res.ID)
+	}
+}
+
+func TestProfilesService_DisableGiftCardIssuer(t *testing.T) {
+	setEnv()
+	setup()
+	defer func() {
+		teardown()
+		unsetEnv()
+	}()
+	
+	id := "pfl_v9hTwCvYqw"
+	
+	tMux.HandleFunc(
+		fmt.Sprintf("/v2/profiles/%s/methods/giftcard/issuers/%s", id, Festivalcadeau),
+		func(rw http.ResponseWriter, r *http.Request) {
+			testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
+			testMethod(t, r, "DELETE")
+			if _, ok := r.Header[AuthHeader]; !ok {
+				rw.WriteHeader(http.StatusUnauthorized)
+			}
+			
+			rw.WriteHeader(http.StatusNoContent)
+		},
+	)
+	
+	err := tClient.Profiles.DisableGiftCardIssuer(id, Festivalcadeau)
+	
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestProfilesService_EnableGiftCardIssuerForCurrent(t *testing.T) {
+	setEnv()
+	setup()
+	defer func() {
+		teardown()
+		unsetEnv()
+	}()
+	
+	id := "me"
+	
+	tMux.HandleFunc(
+		fmt.Sprintf("/v2/profiles/%s/methods/giftcard/issuers/%s", id, Festivalcadeau),
+		func(rw http.ResponseWriter, r *http.Request) {
+			testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
+			testMethod(t, r, "POST")
+			if _, ok := r.Header[AuthHeader]; !ok {
+				rw.WriteHeader(http.StatusUnauthorized)
+			}
+			
+			rw.WriteHeader(http.StatusOK)
+			_, _ = rw.Write([]byte(testdata.EnableGiftCardIssuerResponse))
+		},
+	)
+	
+	res, err := tClient.Profiles.EnableGiftCardIssuerForCurrent(Festivalcadeau)
+	
+	if err != nil {
+		t.Error(err)
+	}
+	
+	if res.ID != Festivalcadeau {
+		t.Errorf("unexpected id received: want %v, got %v", Festivalcadeau, res.ID)
+	}
+}
+
+func TestProfilesService_DisableGiftCardIssuerForCurrent(t *testing.T) {
+	setEnv()
+	setup()
+	defer func() {
+		teardown()
+		unsetEnv()
+	}()
+	
+	id := "me"
+	
+	tMux.HandleFunc(
+		fmt.Sprintf("/v2/profiles/%s/methods/giftcard/issuers/%s", id, Festivalcadeau),
+		func(rw http.ResponseWriter, r *http.Request) {
+			testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
+			testMethod(t, r, "DELETE")
+			if _, ok := r.Header[AuthHeader]; !ok {
+				rw.WriteHeader(http.StatusUnauthorized)
+			}
+			
+			rw.WriteHeader(http.StatusNoContent)
+		},
+	)
+	
+	err := tClient.Profiles.DisableGiftCardIssuerForCurrent(Festivalcadeau)
+	
+	if err != nil {
+		t.Error(err)
+	}
+}
+
 func TestProfilesService_HttpRequestErrors(t *testing.T) {
 	setup()
 	defer teardown()
@@ -285,8 +414,12 @@ func TestProfilesService_HttpRequestErrors(t *testing.T) {
 	_, ccerr := tClient.Profiles.Current()
 	dderr := tClient.Profiles.DisablePaymentMethod("1212", PayPal)
 	_, eperr := tClient.Profiles.EnablePaymentMethod("1212", PayPal)
+	dgcerr := tClient.Profiles.DisableGiftCardIssuer("1212", Festivalcadeau)
+	_, egcerr := tClient.Profiles.EnableGiftCardIssuer("1212", Festivalcadeau)
+	dgccerr := tClient.Profiles.DisableGiftCardIssuerForCurrent(Festivalcadeau)
+	_, egccerr := tClient.Profiles.EnableGiftCardIssuerForCurrent(Festivalcadeau)
 
-	tests := []error{cerr, rerr, uerr, derr, gerr, ccerr, eperr, dderr}
+	tests := []error{cerr, rerr, uerr, derr, gerr, ccerr, eperr, dderr, dgcerr, egcerr, dgccerr, egccerr}
 
 	for _, tt := range tests {
 		if tt == nil {
@@ -308,8 +441,10 @@ func TestProfilesService_EncodingResponseErrors(t *testing.T) {
 	_, gerr := tClient.Profiles.Get("1212")
 	_, ccerr := tClient.Profiles.Current()
 	_, eperr := tClient.Profiles.EnablePaymentMethod("1212", PayPal)
+	_, egcerr := tClient.Profiles.EnableGiftCardIssuer("1212", Festivalcadeau)
+	_, egccerr := tClient.Profiles.EnableGiftCardIssuerForCurrent(Festivalcadeau)
 
-	tests := []error{cerr, rerr, uerr, gerr, ccerr, eperr}
+	tests := []error{cerr, rerr, uerr, gerr, ccerr, eperr, egcerr, egccerr}
 
 	for _, tt := range tests {
 		if tt == nil {
@@ -337,8 +472,10 @@ func TestProfilesService_NewAPIRequestBaseError(t *testing.T) {
 	ddcerr := tClient.Profiles.Delete("1212")
 	_, eperr := tClient.Profiles.EnablePaymentMethod("1212", PayPal)
 	deperr := tClient.Profiles.DisablePaymentMethod("1212", PayPal)
+	dgcerr := tClient.Profiles.DisableGiftCardIssuer("1212", Festivalcadeau)
+	_, egcerr := tClient.Profiles.EnableGiftCardIssuer("1212", Festivalcadeau)
 
-	tests := []error{cerr, rerr, uerr, gerr, ccerr, eperr, deperr, ddcerr}
+	tests := []error{cerr, rerr, uerr, gerr, ccerr, eperr, deperr, ddcerr, dgcerr, egcerr}
 
 	for _, tt := range tests {
 		if tt != errBadBaseURL {
diff --git a/testdata/profiles.go b/testdata/profiles.go
index 2b0e8fc..a71f84c 100644
--- a/testdata/profiles.go
+++ b/testdata/profiles.go
@@ -233,3 +233,22 @@ const EnablePaymentMethodResponse = `{
     }
 }
 `
+
+// EnableGiftCardIssuerResponse example.
+const EnableGiftCardIssuerResponse = `{
+    "resource": "issuer",
+    "id": "festivalcadeau",
+    "description": "FestivalCadeau Giftcard",
+    "status": "pending-issuer",
+    "_links": {
+        "self": {
+            "href": "https://api.mollie.com/v2/issuers/festivalcadeau",
+            "type": "application/hal+json"
+        },
+        "documentation": {
+            "href": "https://docs.mollie.com/reference/v2/profiles-api/enable-giftcard-issuer",
+            "type": "text/html"
+        }
+    }
+}
+`