@@ -76,4 +76,137 @@ defmodule ValidateDocUpdateTest do
7676
7777 assert resp . status_code == 403
7878 end
79+
80+ @ mango_type_check % {
81+ language: "query" ,
82+
83+ validate_doc_update: % {
84+ "newDoc" => % { "type" => % { "$exists" => true } }
85+ }
86+ }
87+
88+ @ tag :with_db
89+ test "Mango VDU accepts a valid document" , context do
90+ db = context [ :db_name ]
91+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: @ mango_type_check )
92+ assert resp . status_code == 201
93+
94+ resp = Couch . put ( "/#{ db } /doc" , body: % { "type" => "movie" } )
95+ assert resp . status_code == 201
96+ assert resp . body [ "ok" ] == true
97+ end
98+
99+ @ tag :with_db
100+ test "Mango VDU rejects an invalid document" , context do
101+ db = context [ :db_name ]
102+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: @ mango_type_check )
103+ assert resp . status_code == 201
104+
105+ resp = Couch . put ( "/#{ db } /doc" , body: % { "no" => "type" } )
106+ assert resp . status_code == 403
107+ assert resp . body [ "error" ] == "forbidden"
108+ end
109+
110+ @ tag :with_db
111+ test "updating a Mango VDU updates its effects" , context do
112+ db = context [ :db_name ]
113+
114+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: @ mango_type_check )
115+ assert resp . status_code == 201
116+
117+ ddoc = % {
118+ language: "query" ,
119+
120+ validate_doc_update: % {
121+ "newDoc" => % {
122+ "type" => % { "$type" => "string" } ,
123+ "year" => % { "$lt" => 2026 }
124+ }
125+ }
126+ }
127+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: ddoc , query: % { rev: resp . body [ "rev" ] } )
128+ assert resp . status_code == 201
129+
130+ resp = Couch . put ( "/#{ db } /doc1" , body: % { "type" => "movie" , "year" => 1994 } )
131+ assert resp . status_code == 201
132+
133+ resp = Couch . put ( "/#{ db } /doc2" , body: % { "type" => 42 , "year" => 1994 } )
134+ assert resp . status_code == 403
135+ assert resp . body [ "error" ] == "forbidden"
136+
137+ resp = Couch . put ( "/#{ db } /doc3" , body: % { "type" => "movie" , "year" => 2094 } )
138+ assert resp . status_code == 403
139+ assert resp . body [ "error" ] == "forbidden"
140+ end
141+
142+ @ tag :with_db
143+ test "converting a Mango VDU to JavaScript updates its effects" , context do
144+ db = context [ :db_name ]
145+
146+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: @ mango_type_check )
147+ assert resp . status_code == 201
148+
149+ ddoc = % {
150+ language: "javascript" ,
151+
152+ validate_doc_update: ~s"""
153+ function (newDoc) {
154+ if (typeof newDoc.year !== 'number') {
155+ throw {forbidden: 'Documents must have a valid year field'};
156+ }
157+ }
158+ """
159+ }
160+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: ddoc , query: % { rev: resp . body [ "rev" ] } )
161+ assert resp . status_code == 201
162+
163+ resp = Couch . put ( "/#{ db } /doc1" , body: % { "year" => 1994 } )
164+ assert resp . status_code == 201
165+
166+ resp = Couch . put ( "/#{ db } /doc2" , body: % { "year" => "1994" } )
167+ assert resp . status_code == 403
168+ assert resp . body [ "error" ] == "forbidden"
169+ end
170+
171+ @ tag :with_db
172+ test "deleting a Mango VDU removes its effects" , context do
173+ db = context [ :db_name ]
174+
175+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: @ mango_type_check )
176+ assert resp . status_code == 201
177+
178+ resp = Couch . delete ( "/#{ db } /_design/mango-test" , query: % { rev: resp . body [ "rev" ] } )
179+ assert resp . status_code == 200
180+
181+ resp = Couch . put ( "/#{ db } /doc" , body: % { "no" => "type" } )
182+ assert resp . status_code == 201
183+ end
184+
185+ @ tag :with_db
186+ test "Mango VDU rejects a doc if any existing ddoc fails to match" , context do
187+ db = context [ :db_name ]
188+ resp = Couch . put ( "/#{ db } /_design/mango-test" , body: @ mango_type_check )
189+ assert resp . status_code == 201
190+
191+ ddoc = % {
192+ language: "query" ,
193+
194+ validate_doc_update: % {
195+ "newDoc" => % { "year" => % { "$lt" => 2026 } }
196+ }
197+ }
198+ resp = Couch . put ( "/#{ db } /_design/mango-test-2" , body: ddoc )
199+ assert resp . status_code == 201
200+
201+ resp = Couch . put ( "/#{ db } /doc1" , body: % { "type" => "movie" , "year" => 1994 } )
202+ assert resp . status_code == 201
203+
204+ resp = Couch . put ( "/#{ db } /doc2" , body: % { "year" => 1994 } )
205+ assert resp . status_code == 403
206+ assert resp . body [ "error" ] == "forbidden"
207+
208+ resp = Couch . put ( "/#{ db } /doc3" , body: % { "type" => "movie" , "year" => 2094 } )
209+ assert resp . status_code == 403
210+ assert resp . body [ "error" ] == "forbidden"
211+ end
79212end
0 commit comments