Skip to content

Commit 446a5cd

Browse files
committed
entries: added feature description & test implementation
Also fixed some bugs in the process
1 parent 77c2103 commit 446a5cd

File tree

3 files changed

+135
-7
lines changed

3 files changed

+135
-7
lines changed

cmd/entries.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func projectAndServiceId() (projectId, servicesId string) {
173173
createServiceId = application.Conf.Get("serviceId")
174174
}
175175

176-
return projectId, servicesId
176+
return createProjectId, createServiceId
177177
}
178178

179179
var entriesEditCommand = &cobra.Command{
@@ -271,7 +271,7 @@ var entriesDeleteCommand = &cobra.Command{
271271
Use: "delete",
272272
Short: "deletes a time entry",
273273
RunE: func(cmd *cobra.Command, args []string) error {
274-
entryId, err := domain.ParseTimeEntryId(editTimeEntryId)
274+
entryId, err := domain.ParseTimeEntryId(deleteTimeEntryId)
275275
if err != nil {
276276
return err
277277
}

tests/feature_test.go

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package tests_test
22

33
import (
4+
"bytes"
5+
"encoding/json"
46
"errors"
57
"flag"
68
"fmt"
@@ -12,6 +14,7 @@ import (
1214
"net/http/httptest"
1315
"os"
1416
"path/filepath"
17+
"reflect"
1518
"strings"
1619
"testing"
1720
)
@@ -54,16 +57,23 @@ func FeatureContext(s *godog.Suite) {
5457
s.Step(`^A local mock server is setup for the http method "([^"]*)" and path "([^"]*)" which returns:$`, c.aLocalMockServerIsSetupForTheHttpMethodAndPathWhichReturns)
5558
s.Step(`^Mite is setup to connect to this mock server$`, c.miteIsSetupToConnectToThisMockServer)
5659
s.Step(`^"([^"]*)" should return the following:$`, c.shouldReturnTheFollowing)
60+
s.Step(`^A local mock server is setup for the http method "([^"]*)" and path "([^"]*)" which expects a body of:$`, c.aLocalMockServerIsSetupForTheHttpMethodAndPathWhichExpectsABodyOf)
61+
s.Step(`^The mock server returns the following if the expectation is met:$`, c.theMockServerReturnsTheFollowingIfTheExpectationIsMet)
5762
}
5863

5964
var opt = godog.Options{
6065
Output: colors.Colored(os.Stdout),
6166
Format: "progress", // can define default values
6267
}
6368

69+
type ReplyGenerator func() string
70+
6471
type cmdTest struct {
6572
executor *executor.Config
66-
mockServer *httptest.Server
73+
mockServer struct {
74+
Server *httptest.Server
75+
ReplyGenerator ReplyGenerator
76+
}
6777
}
6878

6979
func (c *cmdTest) reset(interface{}, error) {
@@ -73,8 +83,8 @@ func (c *cmdTest) reset(interface{}, error) {
7383
}
7484
c.executor = executor.Executor(buildDirectory)
7585

76-
if c.mockServer != nil {
77-
c.mockServer.Close()
86+
if c.mockServer.Server != nil {
87+
c.mockServer.Server.Close()
7888
}
7989
}
8090

@@ -118,7 +128,7 @@ func (c *cmdTest) aLocalMockServerIsSetupForTheHttpMethodAndPathWhichReturns(arg
118128
}
119129
}
120130
handlerFunc := http.HandlerFunc(handler)
121-
c.mockServer = httptest.NewServer(handlerFunc)
131+
c.mockServer.Server = httptest.NewServer(handlerFunc)
122132
return nil
123133
}
124134

@@ -127,7 +137,7 @@ func (c *cmdTest) miteIsSetupToConnectToThisMockServer() error {
127137
if err != nil {
128138
return err
129139
}
130-
err = c.iExecute(fmt.Sprintf("-c .mite.toml config api.url=%s", c.mockServer.URL))
140+
err = c.iExecute(fmt.Sprintf("-c .mite.toml config api.url=%s", c.mockServer.Server.URL))
131141
if err != nil {
132142
return err
133143
}
@@ -142,9 +152,74 @@ func (c *cmdTest) shouldReturnTheFollowing(arg1 string, arg2 *gherkin.DocString)
142152
return assertEqual(strings.TrimSpace(arg2.Content), strings.TrimSpace(string(actualOutput)))
143153
}
144154

155+
func (c *cmdTest) aLocalMockServerIsSetupForTheHttpMethodAndPathWhichExpectsABodyOf(method, path string, expectedBody *gherkin.DocString) error {
156+
handler := func(w http.ResponseWriter, r *http.Request) {
157+
if r.Method != method {
158+
w.WriteHeader(400)
159+
return
160+
}
161+
if r.URL.Path != path {
162+
w.WriteHeader(400)
163+
return
164+
}
165+
buf := new(bytes.Buffer)
166+
_, err := buf.ReadFrom(r.Body)
167+
if err != nil {
168+
w.WriteHeader(400)
169+
return
170+
}
171+
body := buf.String()
172+
err = assertEqualJson(strings.TrimSpace(body), strings.TrimSpace(expectedBody.Content))
173+
if err != nil {
174+
w.WriteHeader(400)
175+
return
176+
}
177+
178+
w.WriteHeader(200)
179+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
180+
replyBody := c.mockServer.ReplyGenerator()
181+
_, err = w.Write([]byte(replyBody))
182+
if err != nil {
183+
panic(err)
184+
}
185+
}
186+
handlerFunc := http.HandlerFunc(handler)
187+
c.mockServer.Server = httptest.NewServer(handlerFunc)
188+
return nil
189+
}
190+
191+
func (c *cmdTest) theMockServerReturnsTheFollowingIfTheExpectationIsMet(replyBody *gherkin.DocString) error {
192+
c.mockServer.ReplyGenerator = func() string {
193+
return replyBody.Content
194+
}
195+
196+
return nil
197+
}
198+
145199
func assertEqual(expected, actual string) error {
146200
if strings.Compare(expected, actual) != 0 {
147201
return errors.New(fmt.Sprintf("expected: \n%s\n to equal: \n%s", expected, actual))
148202
}
149203
return nil
150204
}
205+
206+
func assertEqualJson(s1, s2 string) error {
207+
var o1 interface{}
208+
var o2 interface{}
209+
210+
var err error
211+
err = json.Unmarshal([]byte(s1), &o1)
212+
if err != nil {
213+
return err
214+
}
215+
err = json.Unmarshal([]byte(s2), &o2)
216+
if err != nil {
217+
return err
218+
}
219+
220+
if !reflect.DeepEqual(o1, o2) {
221+
return errors.New("json not deep equal")
222+
}
223+
224+
return nil
225+
}

tests/features/entries.feature

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,56 @@ Feature: entries
3838
-- ----- ---- ---- ------- -------
3939
36159117 Feedback einarbeiten 2015-10-16 15m API v2 Entwurf
4040
"""
41+
Scenario: create entries
42+
Given A local mock server is setup for the http method "POST" and path "/time_entries.json" which expects a body of:
43+
"""
44+
{
45+
"time_entry": {
46+
"date_at": "2015-09-12",
47+
"minutes": 185,
48+
"note": "foo",
49+
"service_id": 243,
50+
"project_id": 123
51+
}
52+
}
53+
"""
54+
And The mock server returns the following if the expectation is met:
55+
"""
56+
{
57+
"time_entry": {
58+
"id": 52324,
59+
"minutes": 185,
60+
"date_at": "2015-09-12",
61+
"note": "foo",
62+
"billable": true,
63+
"locked": false,
64+
"revenue": null,
65+
"hourly_rate": 0,
66+
"user_id": 211,
67+
"user_name": "Fridolin Frei",
68+
"project_id": 123,
69+
"project_name": "Mite",
70+
"service_id": 243,
71+
"service_name": "Dokumentation",
72+
"created_at": "2015-09-13T18:54:45+02:00",
73+
"updated_at": "2015-09-13T18:54:45+02:00"
74+
}
75+
}
76+
"""
77+
And Mite is setup to connect to this mock server
78+
Then "-c .mite.toml entries create -D 2015-09-12 -d 185m -p 123 -s 243 -n foo" should return the following:
79+
"""
80+
id notes date time project service
81+
-- ----- ---- ---- ------- -------
82+
52324 foo 2015-09-12 3h5m Mite Dokumentation
83+
"""
84+
Scenario: delete entries
85+
Given A local mock server is setup for the http method "DELETE" and path "/time_entries/123.json" which returns:
86+
"""
87+
"""
88+
And Mite is setup to connect to this mock server
89+
Then "-c .mite.toml entries delete -i123" should return the following:
90+
"""
91+
"""
92+
93+

0 commit comments

Comments
 (0)