1package db
2
3import (
4	"context"
5
6	"github.com/flimzy/kivik"
7	"github.com/go-kivik/kiviktest/kt"
8)
9
10func init() {
11	kt.Register("Put", put)
12}
13
14func put(ctx *kt.Context) {
15	ctx.RunRW(func(ctx *kt.Context) {
16		ctx.RunAdmin(func(ctx *kt.Context) {
17			testPut(ctx, ctx.Admin)
18		})
19		ctx.RunNoAuth(func(ctx *kt.Context) {
20			testPut(ctx, ctx.NoAuth)
21		})
22	})
23}
24
25func testPut(ctx *kt.Context, client *kivik.Client) {
26	ctx.Parallel()
27	dbName := ctx.TestDB()
28	defer ctx.Admin.DestroyDB(context.Background(), dbName, ctx.Options("db")) // nolint: errcheck
29	db, e := client.DB(context.Background(), dbName, ctx.Options("db"))
30	if !ctx.IsExpectedSuccess(e) {
31		return
32	}
33	ctx.Run("group", func(ctx *kt.Context) {
34		ctx.Run("Create", func(ctx *kt.Context) {
35			ctx.Parallel()
36
37			doc := &testDoc{
38				ID:   ctx.TestDBName(),
39				Name: "Alberto",
40				Age:  32,
41			}
42			var rev string
43			err := kt.Retry(func() error {
44				var err error
45				rev, err = db.Put(context.Background(), doc.ID, doc)
46				return err
47			})
48			if !ctx.IsExpectedSuccess(err) {
49				return
50			}
51			doc.Rev = rev
52			doc.Age = 40
53			ctx.Run("Update", func(ctx *kt.Context) {
54				_, err = db.Put(context.Background(), doc.ID, doc)
55				ctx.CheckError(err)
56			})
57		})
58		ctx.Run("DesignDoc", func(ctx *kt.Context) {
59			ctx.Parallel()
60			doc := map[string]interface{}{
61				"_id":      "_design/testddoc",
62				"language": "javascript",
63				"views": map[string]interface{}{
64					"testview": map[string]interface{}{
65						"map": `function(doc) {
66			                if (doc.include) {
67			                    emit(doc._id, doc.index);
68			                }
69			            }`,
70					},
71				},
72			}
73			err := kt.Retry(func() error {
74				_, err := db.Put(context.Background(), doc["_id"].(string), doc)
75				return err
76			})
77			ctx.CheckError(err)
78		})
79		ctx.Run("Local", func(ctx *kt.Context) {
80			ctx.Parallel()
81			doc := map[string]interface{}{
82				"_id":  "_local/foo",
83				"name": "Bob",
84			}
85			err := kt.Retry(func() error {
86				_, err := db.Put(context.Background(), doc["_id"].(string), doc)
87				return err
88			})
89			ctx.CheckError(err)
90		})
91		ctx.Run("LeadingUnderscoreInID", func(ctx *kt.Context) {
92			ctx.Parallel()
93			doc := map[string]interface{}{
94				"_id":  "_badid",
95				"name": "Bob",
96			}
97			err := kt.Retry(func() error {
98				_, err := db.Put(context.Background(), doc["_id"].(string), doc)
99				return err
100			})
101			ctx.CheckError(err)
102		})
103		ctx.Run("HeavilyEscapedID", func(ctx *kt.Context) {
104			ctx.Parallel()
105			doc := map[string]interface{}{
106				"_id":  "foo+bar & spáces ?!*,",
107				"name": "Bob",
108			}
109			err := kt.Retry(func() error {
110				_, err := db.Put(context.Background(), doc["_id"].(string), doc)
111				return err
112			})
113			ctx.CheckError(err)
114		})
115		ctx.Run("SlashInID", func(ctx *kt.Context) {
116			ctx.Parallel()
117			doc := map[string]interface{}{
118				"_id":  "foo/bar",
119				"name": "Bob",
120			}
121			err := kt.Retry(func() error {
122				_, err := db.Put(context.Background(), doc["_id"].(string), doc)
123				return err
124			})
125			ctx.CheckError(err)
126		})
127		ctx.Run("Conflict", func(ctx *kt.Context) {
128			ctx.Parallel()
129			doc := map[string]interface{}{
130				"_id":  "duplicate",
131				"name": "Bob",
132			}
133			err := kt.Retry(func() error {
134				_, err := db.Put(context.Background(), doc["_id"].(string), doc)
135				return err
136			})
137			if err != nil {
138				ctx.Fatalf("Failed to create document for duplicate test: %s", err)
139			}
140			err = kt.Retry(func() error {
141				_, err = db.Put(context.Background(), doc["_id"].(string), doc)
142				return err
143			})
144			ctx.CheckError(err)
145		})
146	})
147}
148