diff options
Diffstat (limited to 'test/javascript/tests/attachments_multipart.js')
-rw-r--r-- | test/javascript/tests/attachments_multipart.js | 426 |
1 files changed, 0 insertions, 426 deletions
diff --git a/test/javascript/tests/attachments_multipart.js b/test/javascript/tests/attachments_multipart.js deleted file mode 100644 index 793c8c9ec..000000000 --- a/test/javascript/tests/attachments_multipart.js +++ /dev/null @@ -1,426 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -couchTests.elixir = true; -couchTests.attachments_multipart= function(debug) { - return console.log('done in test/elixir/test/attachment_multipart_test.exs'); - var db_name = get_random_db_name() - var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); - db.createDb(); - if (debug) debugger; - - // mime multipart - - var xhr = CouchDB.request("PUT", "/" + db_name + "/multipart", { - headers: {"Content-Type": "multipart/related;boundary=\"abc123\""}, - body: - "--abc123\r\n" + - "content-type: application/json\r\n" + - "\r\n" + - JSON.stringify({ - "body":"This is a body.", - "_attachments":{ - "foo.txt": { - "follows":true, - "content_type":"application/test", - "length":21 - }, - "bar.txt": { - "follows":true, - "content_type":"application/test", - "length":20 - }, - "baz.txt": { - "follows":true, - "content_type":"text/plain", - "length":19 - } - } - }) + - "\r\n--abc123\r\n" + - "\r\n" + - "this is 21 chars long" + - "\r\n--abc123\r\n" + - "\r\n" + - "this is 20 chars lon" + - "\r\n--abc123\r\n" + - "\r\n" + - "this is 19 chars lo" + - "\r\n--abc123--epilogue" - }); - - var result = JSON.parse(xhr.responseText); - - T(result.ok); - - - - TEquals(201, xhr.status, "should send 201 Accepted"); - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart/foo.txt"); - - T(xhr.responseText == "this is 21 chars long"); - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart/bar.txt"); - - T(xhr.responseText == "this is 20 chars lon"); - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart/baz.txt"); - - T(xhr.responseText == "this is 19 chars lo"); - - // now edit an attachment - - var doc = db.open("multipart", {att_encoding_info: true}); - var firstrev = doc._rev; - - T(doc._attachments["foo.txt"].stub == true); - T(doc._attachments["bar.txt"].stub == true); - T(doc._attachments["baz.txt"].stub == true); - TEquals("undefined", typeof doc._attachments["foo.txt"].encoding); - TEquals("undefined", typeof doc._attachments["bar.txt"].encoding); - TEquals("gzip", doc._attachments["baz.txt"].encoding); - - //lets change attachment bar - delete doc._attachments["bar.txt"].stub; // remove stub member (or could set to false) - delete doc._attachments["bar.txt"].digest; // remove the digest (it's for the gzip form) - doc._attachments["bar.txt"].length = 18; - doc._attachments["bar.txt"].follows = true; - //lets delete attachment baz: - delete doc._attachments["baz.txt"]; - - var xhr = CouchDB.request("PUT", "/" + db_name + "/multipart", { - headers: {"Content-Type": "multipart/related;boundary=\"abc123\""}, - body: - "--abc123\r\n" + - "content-type: application/json\r\n" + - "\r\n" + - JSON.stringify(doc) + - "\r\n--abc123\r\n" + - "\r\n" + - "this is 18 chars l" + - "\r\n--abc123--" - }); - TEquals(201, xhr.status); - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart/bar.txt"); - - T(xhr.responseText == "this is 18 chars l"); - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart/baz.txt"); - T(xhr.status == 404); - - // now test receiving multipart docs - - function getBoundary(xhr) { - var ctype = CouchDB.xhrheader(xhr, "Content-Type"); - var ctypeArgs = ctype.split("; ").slice(1); - var boundary = null; - for(var i=0; i<ctypeArgs.length; i++) { - if (ctypeArgs[i].indexOf("boundary=") == 0) { - boundary = ctypeArgs[i].split("=")[1]; - if (boundary.charAt(0) == '"') { - // stringified boundary, parse as json - // (will maybe not if there are escape quotes) - boundary = JSON.parse(boundary); - } - } - } - return boundary; - } - - function parseMultipart(xhr) { - var boundary = getBoundary(xhr); - var mimetext = CouchDB.xhrbody(xhr); - // strip off leading boundary - var leading = "--" + boundary + "\r\n"; - var last = "\r\n--" + boundary + "--"; - - // strip off leading and trailing boundary - var leadingIdx = mimetext.indexOf(leading) + leading.length; - var trailingIdx = mimetext.indexOf(last); - mimetext = mimetext.slice(leadingIdx, trailingIdx); - - // now split the sections - var sections = mimetext.split(new RegExp("\\r\\n--" + boundary)); - - // spilt out the headers for each section - for(var i=0; i < sections.length; i++) { - var section = sections[i]; - var headerEndIdx = section.indexOf("\r\n\r\n"); - var headersraw = section.slice(0, headerEndIdx).split(/\r\n/); - var body = section.slice(headerEndIdx + 4); - var headers = {}; - for(var j=0; j<headersraw.length; j++) { - var tmp = headersraw[j].split(": "); - headers[tmp[0]] = tmp[1]; - } - sections[i] = {"headers":headers, "body":body}; - } - - return sections; - } - - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart?attachments=true", - {headers:{"accept": "multipart/related,*/*;"}}); - - T(xhr.status == 200); - - // parse out the multipart - var sections = parseMultipart(xhr); - TEquals("790", xhr.getResponseHeader("Content-Length"), - "Content-Length should be correct"); - T(sections.length == 3); - // The first section is the json doc. Check it's content-type. - // Each part carries their own meta data. - TEquals("application/json", sections[0].headers['Content-Type'], - "Content-Type should be application/json for section[0]"); - TEquals("application/test", sections[1].headers['Content-Type'], - "Content-Type should be application/test for section[1]"); - TEquals("application/test", sections[2].headers['Content-Type'], - "Content-Type should be application/test for section[2]"); - - TEquals("21", sections[1].headers['Content-Length'], - "Content-Length should be 21 section[1]"); - TEquals("18", sections[2].headers['Content-Length'], - "Content-Length should be 18 section[2]"); - - TEquals('attachment; filename="foo.txt"', sections[1].headers['Content-Disposition'], - "Content-Disposition should be foo.txt section[1]"); - TEquals('attachment; filename="bar.txt"', sections[2].headers['Content-Disposition'], - "Content-Disposition should be bar.txt section[2]"); - - var doc = JSON.parse(sections[0].body); - - T(doc._attachments['foo.txt'].follows == true); - T(doc._attachments['bar.txt'].follows == true); - - T(sections[1].body == "this is 21 chars long"); - TEquals("this is 18 chars l", sections[2].body, "should be 18 chars long"); - - // now get attachments incrementally (only the attachments changes since - // a certain rev). - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart?atts_since=[\"" + firstrev + "\"]", - {headers:{"accept": "multipart/related, */*"}}); - - T(xhr.status == 200); - - var sections = parseMultipart(xhr); - - T(sections.length == 2); - - var doc = JSON.parse(sections[0].body); - - T(doc._attachments['foo.txt'].stub == true); - T(doc._attachments['bar.txt'].follows == true); - - TEquals("this is 18 chars l", sections[1].body, "should be 18 chars long 2"); - - // try the atts_since parameter together with the open_revs parameter - xhr = CouchDB.request( - "GET", - "/" + db_name + "/multipart?open_revs=[" + - '"' + doc._rev + '"]&atts_since=["' + firstrev + '"]', - {headers: {"accept": "multipart/mixed"}} - ); - - T(xhr.status === 200); - - sections = parseMultipart(xhr); - // 1 section, with a multipart/related Content-Type - T(sections.length === 1); - T(sections[0].headers['Content-Type'].indexOf('multipart/related;') === 0); - - var innerSections = parseMultipart(sections[0]); - // 2 inner sections: a document body section plus an attachment data section -// TODO: why does atts_since not work? -// T(innerSections.length === 2); - T(innerSections.length === 3); - T(innerSections[0].headers['Content-Type'] === 'application/json'); - - doc = JSON.parse(innerSections[0].body); - -// TODO: why does atts_since not work? -// T(doc._attachments['foo.txt'].stub === true); - T(doc._attachments['foo.txt'].follows === true); - T(doc._attachments['bar.txt'].follows === true); - -// TODO: why does atts_since not work? - T(innerSections[1].body === "this is 21 chars long"); - T(innerSections[2].body === "this is 18 chars l"); - - // try it with a rev that doesn't exist (should get all attachments) - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart?atts_since=[\"1-2897589\"]", - {headers:{"accept": "multipart/related,*/*;"}}); - - T(xhr.status == 200); - - var sections = parseMultipart(xhr); - - T(sections.length == 3); - - var doc = JSON.parse(sections[0].body); - - T(doc._attachments['foo.txt'].follows == true); - T(doc._attachments['bar.txt'].follows == true); - - T(sections[1].body == "this is 21 chars long"); - TEquals("this is 18 chars l", sections[2].body, "should be 18 chars long 3"); - // try it with a rev that doesn't exist, and one that does - - xhr = CouchDB.request("GET", "/" + db_name + "/multipart?atts_since=[\"1-2897589\",\"" + firstrev + "\"]", - {headers:{"accept": "multipart/related,*/*;"}}); - - T(xhr.status == 200); - - var sections = parseMultipart(xhr); - - T(sections.length == 2); - - var doc = JSON.parse(sections[0].body); - - T(doc._attachments['foo.txt'].stub == true); - T(doc._attachments['bar.txt'].follows == true); - - TEquals("this is 18 chars l", sections[1].body, "should be 18 chars long 4"); - - // check that with the document multipart/mixed API it's possible to receive - // attachments in compressed form (if they're stored in compressed form) - - var server_config = [ - { - section: "attachments", - key: "compression_level", - value: "8" - }, - { - section: "attachments", - key: "compressible_types", - value: "text/plain" - } - ]; - - function testMultipartAttCompression() { - var doc = { _id: "foobar" }; - var lorem = - CouchDB.request("GET", "/_utils/script/test/lorem.txt").responseText; - var helloData = "hello world"; - - TEquals(true, db.save(doc).ok); - - var firstRev = doc._rev; - var xhr = CouchDB.request( - "PUT", - "/" + db.name + "/" + doc._id + "/data.bin?rev=" + firstRev, - { - body: helloData, - headers: {"Content-Type": "application/binary"} - } - ); - TEquals(201, xhr.status); - - var secondRev = db.open(doc._id)._rev; - xhr = CouchDB.request( - "PUT", - "/" + db.name + "/" + doc._id + "/lorem.txt?rev=" + secondRev, - { - body: lorem, - headers: {"Content-Type": "text/plain"} - } - ); - TEquals(201, xhr.status); - - var thirdRev = db.open(doc._id)._rev; - - xhr = CouchDB.request( - "GET", - '/' + db.name + '/' + doc._id + '?open_revs=["' + thirdRev + '"]', - { - headers: { - "Accept": "multipart/mixed", - "X-CouchDB-Send-Encoded-Atts": "true" - } - } - ); - TEquals(200, xhr.status); - - var sections = parseMultipart(xhr); - // 1 section, with a multipart/related Content-Type - TEquals(1, sections.length); - TEquals(0, - sections[0].headers['Content-Type'].indexOf('multipart/related;')); - - var innerSections = parseMultipart(sections[0]); - // 3 inner sections: a document body section plus 2 attachment data sections - TEquals(3, innerSections.length); - TEquals('application/json', innerSections[0].headers['Content-Type']); - - doc = JSON.parse(innerSections[0].body); - - TEquals(true, doc._attachments['lorem.txt'].follows); - TEquals("gzip", doc._attachments['lorem.txt'].encoding); - TEquals(true, doc._attachments['data.bin'].follows); - T(doc._attachments['data.bin'] !== "gzip"); - - if (innerSections[1].body === helloData) { - T(innerSections[2].body !== lorem); - } else if (innerSections[2].body === helloData) { - T(innerSections[1].body !== lorem); - } else { - T(false, "Could not found data.bin attachment data"); - } - - // now test that it works together with the atts_since parameter - - xhr = CouchDB.request( - "GET", - '/' + db.name + '/' + doc._id + '?open_revs=["' + thirdRev + '"]' + - '&atts_since=["' + secondRev + '"]', - { - headers: { - "Accept": "multipart/mixed", - "X-CouchDB-Send-Encoded-Atts": "true" - } - } - ); - TEquals(200, xhr.status); - - sections = parseMultipart(xhr); - // 1 section, with a multipart/related Content-Type - TEquals(1, sections.length); - TEquals(0, - sections[0].headers['Content-Type'].indexOf('multipart/related;')); - - innerSections = parseMultipart(sections[0]); - // 2 inner sections: a document body section plus 1 attachment data section -// TODO: why does atts_since not work? -// TEquals(2, innerSections.length); - TEquals('application/json', innerSections[0].headers['Content-Type']); - - doc = JSON.parse(innerSections[0].body); - - TEquals(true, doc._attachments['lorem.txt'].follows); - TEquals("gzip", doc._attachments['lorem.txt'].encoding); -// TODO: why does atts_since not work? -// TEquals("undefined", typeof doc._attachments['data.bin'].follows); -// TEquals(true, doc._attachments['data.bin'].stub); - T(innerSections[1].body !== lorem); - } - - run_on_modified_server(server_config, testMultipartAttCompression); - -// // cleanup - db.deleteDb(); -}; |