1// Copyright 2012-present Oliver Eilhard. All rights reserved.
2// Use of this source code is governed by a MIT-license.
3// See http://olivere.mit-license.org/license.txt for details.
4
5package elastic
6
7import (
8	"context"
9	"encoding/json"
10	"net/url"
11	"testing"
12)
13
14func TestUpdateViaScript(t *testing.T) {
15	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
16
17	update := client.Update().
18		Index("test").Type("type1").Id("1").
19		Script(NewScript("ctx._source.tags += tag").Params(map[string]interface{}{"tag": "blue"}).Lang("groovy"))
20	path, params, err := update.url()
21	if err != nil {
22		t.Fatalf("expected to return URL, got: %v", err)
23	}
24	expectedPath := `/test/type1/1/_update`
25	if expectedPath != path {
26		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
27	}
28	expectedParams := url.Values{}
29	if expectedParams.Encode() != params.Encode() {
30		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
31	}
32	body, err := update.body()
33	if err != nil {
34		t.Fatalf("expected to return body, got: %v", err)
35	}
36	data, err := json.Marshal(body)
37	if err != nil {
38		t.Fatalf("expected to marshal body as JSON, got: %v", err)
39	}
40	got := string(data)
41	expected := `{"script":{"inline":"ctx._source.tags += tag","lang":"groovy","params":{"tag":"blue"}}}`
42	if got != expected {
43		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
44	}
45}
46
47func TestUpdateViaScriptId(t *testing.T) {
48	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
49
50	scriptParams := map[string]interface{}{
51		"pageViewEvent": map[string]interface{}{
52			"url":      "foo.com/bar",
53			"response": 404,
54			"time":     "2014-01-01 12:32",
55		},
56	}
57	script := NewScriptId("my_web_session_summariser").Params(scriptParams)
58
59	update := client.Update().
60		Index("sessions").Type("session").Id("dh3sgudg8gsrgl").
61		Script(script).
62		ScriptedUpsert(true).
63		Upsert(map[string]interface{}{})
64	path, params, err := update.url()
65	if err != nil {
66		t.Fatalf("expected to return URL, got: %v", err)
67	}
68	expectedPath := `/sessions/session/dh3sgudg8gsrgl/_update`
69	if expectedPath != path {
70		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
71	}
72	expectedParams := url.Values{}
73	if expectedParams.Encode() != params.Encode() {
74		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
75	}
76	body, err := update.body()
77	if err != nil {
78		t.Fatalf("expected to return body, got: %v", err)
79	}
80	data, err := json.Marshal(body)
81	if err != nil {
82		t.Fatalf("expected to marshal body as JSON, got: %v", err)
83	}
84	got := string(data)
85	expected := `{"script":{"id":"my_web_session_summariser","params":{"pageViewEvent":{"response":404,"time":"2014-01-01 12:32","url":"foo.com/bar"}}},"scripted_upsert":true,"upsert":{}}`
86	if got != expected {
87		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
88	}
89}
90
91func TestUpdateViaScriptFile(t *testing.T) {
92	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
93
94	scriptParams := map[string]interface{}{
95		"pageViewEvent": map[string]interface{}{
96			"url":      "foo.com/bar",
97			"response": 404,
98			"time":     "2014-01-01 12:32",
99		},
100	}
101	script := NewScriptFile("update_script").Params(scriptParams)
102
103	update := client.Update().
104		Index("sessions").Type("session").Id("dh3sgudg8gsrgl").
105		Script(script).
106		ScriptedUpsert(true).
107		Upsert(map[string]interface{}{})
108
109	path, params, err := update.url()
110	if err != nil {
111		t.Fatalf("expected to return URL, got: %v", err)
112	}
113	expectedPath := `/sessions/session/dh3sgudg8gsrgl/_update`
114	if expectedPath != path {
115		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
116	}
117	expectedParams := url.Values{}
118	if expectedParams.Encode() != params.Encode() {
119		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
120	}
121	body, err := update.body()
122	if err != nil {
123		t.Fatalf("expected to return body, got: %v", err)
124	}
125	data, err := json.Marshal(body)
126	if err != nil {
127		t.Fatalf("expected to marshal body as JSON, got: %v", err)
128	}
129	got := string(data)
130	expected := `{"script":{"file":"update_script","params":{"pageViewEvent":{"response":404,"time":"2014-01-01 12:32","url":"foo.com/bar"}}},"scripted_upsert":true,"upsert":{}}`
131	if got != expected {
132		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
133	}
134}
135
136func TestUpdateViaScriptAndUpsert(t *testing.T) {
137	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
138
139	update := client.Update().
140		Index("test").Type("type1").Id("1").
141		Script(NewScript("ctx._source.counter += count").Params(map[string]interface{}{"count": 4})).
142		Upsert(map[string]interface{}{"counter": 1})
143	path, params, err := update.url()
144	if err != nil {
145		t.Fatalf("expected to return URL, got: %v", err)
146	}
147	expectedPath := `/test/type1/1/_update`
148	if expectedPath != path {
149		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
150	}
151	expectedParams := url.Values{}
152	if expectedParams.Encode() != params.Encode() {
153		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
154	}
155	body, err := update.body()
156	if err != nil {
157		t.Fatalf("expected to return body, got: %v", err)
158	}
159	data, err := json.Marshal(body)
160	if err != nil {
161		t.Fatalf("expected to marshal body as JSON, got: %v", err)
162	}
163	got := string(data)
164	expected := `{"script":{"inline":"ctx._source.counter += count","params":{"count":4}},"upsert":{"counter":1}}`
165	if got != expected {
166		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
167	}
168}
169
170func TestUpdateViaDoc(t *testing.T) {
171	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
172
173	update := client.Update().
174		Index("test").Type("type1").Id("1").
175		Doc(map[string]interface{}{"name": "new_name"}).
176		DetectNoop(true)
177	path, params, err := update.url()
178	if err != nil {
179		t.Fatalf("expected to return URL, got: %v", err)
180	}
181	expectedPath := `/test/type1/1/_update`
182	if expectedPath != path {
183		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
184	}
185	expectedParams := url.Values{}
186	if expectedParams.Encode() != params.Encode() {
187		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
188	}
189	body, err := update.body()
190	if err != nil {
191		t.Fatalf("expected to return body, got: %v", err)
192	}
193	data, err := json.Marshal(body)
194	if err != nil {
195		t.Fatalf("expected to marshal body as JSON, got: %v", err)
196	}
197	got := string(data)
198	expected := `{"detect_noop":true,"doc":{"name":"new_name"}}`
199	if got != expected {
200		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
201	}
202}
203
204func TestUpdateViaDocAndUpsert(t *testing.T) {
205	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
206
207	update := client.Update().
208		Index("test").Type("type1").Id("1").
209		Doc(map[string]interface{}{"name": "new_name"}).
210		DocAsUpsert(true).
211		Timeout("1s").
212		Refresh("true")
213	path, params, err := update.url()
214	if err != nil {
215		t.Fatalf("expected to return URL, got: %v", err)
216	}
217	expectedPath := `/test/type1/1/_update`
218	if expectedPath != path {
219		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
220	}
221	expectedParams := url.Values{"refresh": []string{"true"}, "timeout": []string{"1s"}}
222	if expectedParams.Encode() != params.Encode() {
223		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
224	}
225	body, err := update.body()
226	if err != nil {
227		t.Fatalf("expected to return body, got: %v", err)
228	}
229	data, err := json.Marshal(body)
230	if err != nil {
231		t.Fatalf("expected to marshal body as JSON, got: %v", err)
232	}
233	got := string(data)
234	expected := `{"doc":{"name":"new_name"},"doc_as_upsert":true}`
235	if got != expected {
236		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
237	}
238}
239
240func TestUpdateViaDocAndUpsertAndFetchSource(t *testing.T) {
241	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
242
243	update := client.Update().
244		Index("test").Type("type1").Id("1").
245		Doc(map[string]interface{}{"name": "new_name"}).
246		DocAsUpsert(true).
247		Timeout("1s").
248		Refresh("true").
249		FetchSource(true)
250	path, params, err := update.url()
251	if err != nil {
252		t.Fatalf("expected to return URL, got: %v", err)
253	}
254	expectedPath := `/test/type1/1/_update`
255	if expectedPath != path {
256		t.Errorf("expected URL path\n%s\ngot:\n%s", expectedPath, path)
257	}
258	expectedParams := url.Values{
259		"refresh": []string{"true"},
260		"timeout": []string{"1s"},
261	}
262	if expectedParams.Encode() != params.Encode() {
263		t.Errorf("expected URL parameters\n%s\ngot:\n%s", expectedParams.Encode(), params.Encode())
264	}
265	body, err := update.body()
266	if err != nil {
267		t.Fatalf("expected to return body, got: %v", err)
268	}
269	data, err := json.Marshal(body)
270	if err != nil {
271		t.Fatalf("expected to marshal body as JSON, got: %v", err)
272	}
273	got := string(data)
274	expected := `{"_source":true,"doc":{"name":"new_name"},"doc_as_upsert":true}`
275	if got != expected {
276		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
277	}
278}
279
280func TestUpdateAndFetchSource(t *testing.T) {
281	client := setupTestClientAndCreateIndexAndAddDocs(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
282
283	res, err := client.Update().
284		Index(testIndexName).Type("tweet").Id("1").
285		Doc(map[string]interface{}{"user": "sandrae"}).
286		DetectNoop(true).
287		FetchSource(true).
288		Do(context.Background())
289	if err != nil {
290		t.Fatal(err)
291	}
292	if res == nil {
293		t.Fatal("expected response != nil")
294	}
295	if res.GetResult == nil {
296		t.Fatal("expected GetResult != nil")
297	}
298	data, err := json.Marshal(res.GetResult.Source)
299	if err != nil {
300		t.Fatalf("expected to marshal body as JSON, got: %v", err)
301	}
302	got := string(data)
303	expected := `{"user":"sandrae","message":"Welcome to Golang and Elasticsearch.","retweets":0,"created":"0001-01-01T00:00:00Z"}`
304	if got != expected {
305		t.Errorf("expected\n%s\ngot:\n%s", expected, got)
306	}
307}
308