Add code query parameter for action get (#49)

diff --git a/whisk/action.go b/whisk/action.go
index 1bdb879..c1e06ea 100644
--- a/whisk/action.go
+++ b/whisk/action.go
@@ -27,7 +27,7 @@
 )
 
 type ActionService struct {
-	client *Client
+	client ClientInterface
 }
 
 type Action struct {
@@ -231,11 +231,11 @@
 	return a, resp, nil
 }
 
-func (s *ActionService) Get(actionName string) (*Action, *http.Response, error) {
+func (s *ActionService) Get(actionName string, fetchCode bool) (*Action, *http.Response, error) {
 	// Encode resource name as a path (with no query params) before inserting it into the URI
 	// This way any '?' chars in the name won't be treated as the beginning of the query params
 	actionName = (&url.URL{Path: actionName}).String()
-	route := fmt.Sprintf("actions/%s", actionName)
+	route := fmt.Sprintf("actions/%s?code=%t", actionName, fetchCode)
 
 	req, err := s.client.NewRequest("GET", route, nil, IncludeNamespaceInUrl)
 	if err != nil {
diff --git a/whisk/action_test.go b/whisk/action_test.go
new file mode 100644
index 0000000..57f7e66
--- /dev/null
+++ b/whisk/action_test.go
@@ -0,0 +1,151 @@
+//// +build unit
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package whisk
+
+import (
+	"encoding/json"
+	"github.com/stretchr/testify/assert"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"strings"
+	"testing"
+)
+
+const (
+	NODE_ACTION_NO_CODE = `{
+        "name": "test",
+        "publish": false,
+        "annotations": [
+            {
+                "key": "exec",
+                "value": "nodejs:6"
+            }
+        ],
+        "version": "0.0.1",
+        "exec": {
+            "kind": "nodejs:6",
+            "binary": false
+        },
+        "parameters": [],
+        "limits": {
+            "timeout": 60000,
+            "memory": 256,
+            "logs": 10
+        },
+        "namespace": "test@openwhisk"
+    }`
+
+	NODE_ACTION = `{
+        "name": "test",
+        "publish": false,
+        "annotations": [
+            {
+                "key": "exec",
+                "value": "nodejs:6"
+            }
+        ],
+        "version": "0.0.1",
+        "exec": {
+            "kind": "nodejs:6",
+            "code": "...",
+            "binary": false
+        },
+        "parameters": [],
+        "limits": {
+            "timeout": 60000,
+            "memory": 256,
+            "logs": 10
+        },
+        "namespace": "test@openwhisk"
+    }`
+)
+
+type ActionResponse struct {
+	Body string
+}
+
+type ActionRequest struct {
+	Method string
+	URL    string
+}
+
+var actionResponse = &ActionResponse{}
+var actionRequest = &ActionRequest{}
+
+type MockClient struct{}
+
+func (c *MockClient) NewRequestUrl(method string, urlRelResource *url.URL, body interface{}, includeNamespaceInUrl bool, appendOpenWhiskPath bool, encodeBodyAs string, useAuthentication bool) (*http.Request, error) {
+	return &http.Request{}, nil
+}
+
+func (c *MockClient) NewRequest(method, urlStr string, body interface{}, includeNamespaceInUrl bool) (*http.Request, error) {
+	actionRequest.Method = method
+	actionRequest.URL = urlStr
+
+	request, err := http.NewRequest(method, urlStr, nil)
+	if err != nil {
+		return &http.Request{}, err
+	}
+
+	return request, nil
+}
+
+func (c *MockClient) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool, secretToObfuscate ...ObfuscateSet) (*http.Response, error) {
+	var reader = strings.NewReader(actionResponse.Body)
+
+	dc := json.NewDecoder(reader)
+	dc.UseNumber()
+	err := dc.Decode(v)
+
+	if err != nil {
+		return nil, err
+	}
+
+	resp := &http.Response{
+		StatusCode: 200,
+		Body:       ioutil.NopCloser(reader),
+	}
+
+	return resp, nil
+}
+
+func TestActionGet(t *testing.T) {
+	assert := assert.New(t)
+	mockClient := &MockClient{}
+	actionService := &ActionService{client: mockClient}
+
+	actionResponse.Body = NODE_ACTION_NO_CODE
+	action, _, _ := actionService.Get("test", false)
+
+	var exec Exec
+	exec = *action.Exec
+	var nilStr *string
+
+	assert.Equal("GET", actionRequest.Method)
+	assert.Equal("actions/test?code=false", actionRequest.URL)
+	assert.Equal(nilStr, exec.Code)
+
+	actionResponse.Body = NODE_ACTION
+	action, _, _ = actionService.Get("test", true)
+	assert.Equal("GET", actionRequest.Method)
+	assert.Equal("actions/test?code=true", actionRequest.URL)
+	assert.Equal("...", *action.Exec.Code)
+}
diff --git a/whisk/client.go b/whisk/client.go
index 2419da0..d4e8afc 100644
--- a/whisk/client.go
+++ b/whisk/client.go
@@ -51,6 +51,12 @@
 	DEFAULT_HTTP_TIMEOUT           = 30
 )
 
+type ClientInterface interface {
+	NewRequestUrl(method string, urlRelResource *url.URL, body interface{}, includeNamespaceInUrl bool, appendOpenWhiskPath bool, encodeBodyAs string, useAuthentication bool) (*http.Request, error)
+	NewRequest(method, urlStr string, body interface{}, includeNamespaceInUrl bool) (*http.Request, error)
+	Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool, secretToObfuscate ...ObfuscateSet) (*http.Response, error)
+}
+
 type Client struct {
 	client *http.Client
 	*Config