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	"testing"
11)
12
13func TestGeoPointSource(t *testing.T) {
14	pt := GeoPoint{Lat: 40, Lon: -70}
15
16	data, err := json.Marshal(pt.Source())
17	if err != nil {
18		t.Fatalf("marshaling to JSON failed: %v", err)
19	}
20	got := string(data)
21	expected := `{"lat":40,"lon":-70}`
22	if got != expected {
23		t.Errorf("expected\n%s\n,got:\n%s", expected, got)
24	}
25}
26
27func TestGeoPointMarshalJSON(t *testing.T) {
28	pt := GeoPoint{Lat: 40, Lon: -70}
29
30	data, err := json.Marshal(pt)
31	if err != nil {
32		t.Fatalf("marshaling to JSON failed: %v", err)
33	}
34	got := string(data)
35	expected := `{"lat":40,"lon":-70}`
36	if got != expected {
37		t.Errorf("expected\n%s\n,got:\n%s", expected, got)
38	}
39}
40
41func TestGeoPointIndexAndSearch(t *testing.T) {
42	client := setupTestClient(t) // , SetTraceLog(log.New(os.Stdout, "", 0)))
43
44	// Create index
45	mapping := `
46	{
47		"settings":{
48			"number_of_shards":1,
49			"number_of_replicas":0
50		},
51		"mappings":{
52			"doc":{
53				"properties":{
54					"name":{
55						"type":"keyword"
56					},
57					"location":{
58						"type":"geo_point"
59					}
60				}
61			}
62		}
63	}
64`
65	createIndex, err := client.CreateIndex(testIndexName).Body(mapping).Do(context.TODO())
66	if err != nil {
67		t.Fatal(err)
68	}
69	if createIndex == nil {
70		t.Errorf("expected result to be != nil; got: %v", createIndex)
71	}
72
73	// Add document
74	type City struct {
75		Name     string    `json:"name"`
76		Location *GeoPoint `json:"location"`
77	}
78	munich := &City{
79		Name:     "München",
80		Location: GeoPointFromLatLon(48.137154, 11.576124),
81	}
82	_, err = client.Index().Index(testIndexName).Type("doc").Id("1").BodyJson(&munich).Do(context.TODO())
83	if err != nil {
84		t.Fatal(err)
85	}
86
87	// Flush
88	_, err = client.Flush().Index(testIndexName).Do(context.TODO())
89	if err != nil {
90		t.Fatal(err)
91	}
92
93	// Get document
94	q := NewGeoDistanceQuery("location")
95	q = q.GeoPoint(GeoPointFromLatLon(48, 11))
96	q = q.Distance("50km")
97	res, err := client.
98		Search(testIndexName).
99		Type("doc").
100		Query(q).
101		Do(context.TODO())
102	if err != nil {
103		t.Fatal(err)
104	}
105	if want, have := int64(1), res.TotalHits(); want != have {
106		t.Fatalf("TotalHits: want %d, have %d", want, have)
107	}
108	var doc City
109	if err := json.Unmarshal(*res.Hits.Hits[0].Source, &doc); err != nil {
110		t.Fatal(err)
111	}
112	if want, have := munich.Name, doc.Name; want != have {
113		t.Fatalf("Name: want %q, have %q", want, have)
114	}
115	if want, have := munich.Location.Lat, doc.Location.Lat; want != have {
116		t.Fatalf("Lat: want %v, have %v", want, have)
117	}
118	if want, have := munich.Location.Lon, doc.Location.Lon; want != have {
119		t.Fatalf("Lon: want %v, have %v", want, have)
120	}
121}
122