Skip to content

Commit f6e8b73

Browse files
author
Katrina Owen
authored
Merge pull request #641 from exercism/download-uuid
Fix problem with downloading another person's solution using the --uuid flag
2 parents 60207ea + a59e028 commit f6e8b73

2 files changed

Lines changed: 81 additions & 62 deletions

File tree

cmd/download.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,16 @@ func runDownload(cfg config.Configuration, flags *pflag.FlagSet, args []string)
132132
IsRequester: payload.Solution.User.IsRequester,
133133
}
134134

135-
dir := filepath.Join(usrCfg.GetString("workspace"), solution.Track)
136-
os.MkdirAll(dir, os.FileMode(0755))
135+
dir := usrCfg.GetString("workspace")
136+
if !solution.IsRequester {
137+
dir = filepath.Join(dir, "users", solution.Handle)
138+
}
139+
dir = filepath.Join(dir, solution.Track)
137140

138-
var ws workspace.Workspace
139-
if solution.IsRequester {
140-
ws, err = workspace.New(dir)
141-
if err != nil {
142-
return err
143-
}
144-
} else {
145-
ws, err = workspace.New(filepath.Join(usrCfg.GetString("workspace"), "users", solution.Handle, solution.Track))
146-
if err != nil {
147-
return err
148-
}
141+
os.MkdirAll(dir, os.FileMode(0755))
142+
ws, err := workspace.New(dir)
143+
if err != nil {
144+
return err
149145
}
150146

151147
dir, err = ws.SolutionPath(solution.Exercise, solution.ID)

cmd/download_test.go

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestDownloadWithoutFlags(t *testing.T) {
4343
}
4444
}
4545

46-
func TestDownload(t *testing.T) {
46+
func TestDownloadTHISONE(t *testing.T) {
4747
oldOut := Out
4848
oldErr := Err
4949
Out = ioutil.Discard
@@ -53,46 +53,93 @@ func TestDownload(t *testing.T) {
5353
Err = oldErr
5454
}()
5555

56-
tmpDir, err := ioutil.TempDir("", "download-cmd")
57-
assert.NoError(t, err)
56+
testCases := []struct {
57+
requestor string
58+
expectedDir string
59+
flag, flagValue string
60+
}{
61+
{requestorSelf, "", "exercise", "bogus-exercise"},
62+
{requestorSelf, "", "uuid", "bogus-id"},
63+
{requestorOther, filepath.Join("users", "alice"), "uuid", "bogus-id"},
64+
}
5865

59-
ts := fakeDownloadServer()
60-
defer ts.Close()
66+
for _, tc := range testCases {
67+
tmpDir, err := ioutil.TempDir("", "download-cmd")
68+
assert.NoError(t, err)
6169

62-
v := viper.New()
63-
v.Set("workspace", tmpDir)
64-
v.Set("apibaseurl", ts.URL)
65-
v.Set("token", "abc123")
70+
ts := fakeDownloadServer(tc.requestor)
71+
defer ts.Close()
6672

67-
cfg := config.Configuration{
68-
UserViperConfig: v,
73+
v := viper.New()
74+
v.Set("workspace", tmpDir)
75+
v.Set("apibaseurl", ts.URL)
76+
v.Set("token", "abc123")
77+
78+
cfg := config.Configuration{
79+
UserViperConfig: v,
80+
}
81+
flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
82+
setupDownloadFlags(flags)
83+
flags.Set(tc.flag, tc.flagValue)
84+
85+
err = runDownload(cfg, flags, []string{})
86+
assert.NoError(t, err)
87+
88+
assertDownloadedCorrectFiles(t, filepath.Join(tmpDir, tc.expectedDir), tc.requestor)
6989
}
70-
flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
71-
setupDownloadFlags(flags)
72-
flags.Set("exercise", "bogus-exercise")
90+
}
91+
92+
func fakeDownloadServer(requestor string) *httptest.Server {
93+
mux := http.NewServeMux()
94+
server := httptest.NewServer(mux)
7395

74-
err = runDownload(cfg, flags, []string{})
75-
assert.NoError(t, err)
96+
path1 := "file-1.txt"
97+
mux.HandleFunc("/"+path1, func(w http.ResponseWriter, r *http.Request) {
98+
fmt.Fprint(w, "this is file 1")
99+
})
100+
101+
path2 := "subdir/file-2.txt"
102+
mux.HandleFunc("/"+path2, func(w http.ResponseWriter, r *http.Request) {
103+
fmt.Fprint(w, "this is file 2")
104+
})
105+
106+
path3 := "file-3.txt"
107+
mux.HandleFunc("/"+path3, func(w http.ResponseWriter, r *http.Request) {
108+
fmt.Fprint(w, "")
109+
})
76110

111+
payloadBody := fmt.Sprintf(payloadTemplate, requestor, server.URL+"/", path1, path2, path3)
112+
mux.HandleFunc("/solutions/latest", func(w http.ResponseWriter, r *http.Request) {
113+
fmt.Fprint(w, payloadBody)
114+
})
115+
mux.HandleFunc("/solutions/bogus-id", func(w http.ResponseWriter, r *http.Request) {
116+
fmt.Fprint(w, payloadBody)
117+
})
118+
119+
return server
120+
}
121+
122+
func assertDownloadedCorrectFiles(t *testing.T, targetDir, requestor string) {
123+
metadata := `{"track":"bogus-track","exercise":"bogus-exercise","id":"bogus-id","url":"","handle":"alice","is_requester":%s,"auto_approve":false}`
77124
expectedFiles := []struct {
78125
desc string
79126
path string
80127
contents string
81128
}{
82129
{
83130
desc: "a file in the exercise root directory",
84-
path: filepath.Join(tmpDir, "bogus-track", "bogus-exercise", "file-1.txt"),
131+
path: filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-1.txt"),
85132
contents: "this is file 1",
86133
},
87134
{
88135
desc: "a file in a subdirectory",
89-
path: filepath.Join(tmpDir, "bogus-track", "bogus-exercise", "subdir", "file-2.txt"),
136+
path: filepath.Join(targetDir, "bogus-track", "bogus-exercise", "subdir", "file-2.txt"),
90137
contents: "this is file 2",
91138
},
92139
{
93140
desc: "the solution metadata file",
94-
path: filepath.Join(tmpDir, "bogus-track", "bogus-exercise", ".solution.json"),
95-
contents: `{"track":"bogus-track","exercise":"bogus-exercise","id":"bogus-id","url":"","handle":"alice","is_requester":true,"auto_approve":false}`,
141+
path: filepath.Join(targetDir, "bogus-track", "bogus-exercise", ".solution.json"),
142+
contents: fmt.Sprintf(metadata, requestor),
96143
},
97144
}
98145

@@ -104,45 +151,21 @@ func TestDownload(t *testing.T) {
104151
})
105152
}
106153

107-
path := filepath.Join(tmpDir, "bogus-track", "bogus-exercise", "file-3.txt")
108-
_, err = os.Lstat(path)
154+
path := filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-3.txt")
155+
_, err := os.Lstat(path)
109156
assert.True(t, os.IsNotExist(err), "It should not write the file if empty.")
110157
}
111158

112-
func fakeDownloadServer() *httptest.Server {
113-
mux := http.NewServeMux()
114-
server := httptest.NewServer(mux)
115-
116-
path1 := "file-1.txt"
117-
mux.HandleFunc("/"+path1, func(w http.ResponseWriter, r *http.Request) {
118-
fmt.Fprint(w, "this is file 1")
119-
})
120-
121-
path2 := "subdir/file-2.txt"
122-
mux.HandleFunc("/"+path2, func(w http.ResponseWriter, r *http.Request) {
123-
fmt.Fprint(w, "this is file 2")
124-
})
125-
126-
path3 := "file-3.txt"
127-
mux.HandleFunc("/"+path3, func(w http.ResponseWriter, r *http.Request) {
128-
fmt.Fprint(w, "")
129-
})
130-
131-
payloadBody := fmt.Sprintf(payloadTemplate, server.URL+"/", path1, path2, path3)
132-
mux.HandleFunc("/solutions/latest", func(w http.ResponseWriter, r *http.Request) {
133-
fmt.Fprint(w, payloadBody)
134-
})
135-
136-
return server
137-
}
159+
const requestorSelf = "true"
160+
const requestorOther = "false"
138161

139162
const payloadTemplate = `
140163
{
141164
"solution": {
142165
"id": "bogus-id",
143166
"user": {
144167
"handle": "alice",
145-
"is_requester": true
168+
"is_requester": %s
146169
},
147170
"exercise": {
148171
"id": "bogus-exercise",

0 commit comments

Comments
 (0)