diff --git a/src/base.ts b/src/base.ts index 5e4fbc9f..11836a95 100644 --- a/src/base.ts +++ b/src/base.ts @@ -7,11 +7,11 @@ import { cleanUndefinedProperties, } from "./utils"; import HTTP, { HttpResponse } from "./http"; -import endpoint from "./endpoint"; +import endpoints from "./endpoints"; import * as requests from "./requests"; import { aggregate, AggregateResponse } from "./batch"; import Bucket from "./bucket"; -import { capable } from "./utils"; +import { addEndpointOptions, capable } from "./utils"; import { HelloResponse, KintoRequest, @@ -90,6 +90,7 @@ export default class KintoClientBase { public serverInfo: HelloResponse | null; public events?: Emitter; public http: HTTP; + public endpoints: typeof endpoints; private _remote!: string; private _version!: string; @@ -141,6 +142,8 @@ export default class KintoClientBase { */ this.events = options.events; + this.endpoints = endpoints; + const { requestMode, timeout } = options; /** * The HTTP instance. @@ -311,7 +314,7 @@ export default class KintoClientBase { headers?: Record; } = {} ): Promise { - const path = this.remote + endpoint.root(); + const path = this.remote + endpoints.root(); const { json } = await this.http.request( path, { headers: this._getHeaders(options) }, @@ -450,7 +453,7 @@ export default class KintoClientBase { // FIXME: is this really necessary, since it's also present in // the "defaults"? headers, - path: endpoint.batch(), + path: endpoints.batch(), method: "POST", body: { defaults: { headers }, @@ -534,7 +537,13 @@ export default class KintoClientBase { */ async execute( request: KintoRequest, - options: { raw?: boolean; stringify?: boolean; retry?: number } = {} + options: { + raw?: boolean; + stringify?: boolean; + retry?: number; + query?: { [key: string]: string }; + fields?: string[]; + } = {} ): Promise> { const { raw = false, stringify = true } = options; // If we're within a batch, add the request to the stack to send at once. @@ -551,8 +560,9 @@ export default class KintoClientBase { ? ({ status: 0, json: msg, headers: new Headers() } as HttpResponse) : msg; } + const uri = this.remote + addEndpointOptions(request.path, options); const result = await this.http.request( - this.remote + request.path, + uri, cleanUndefinedProperties({ // Limit requests to only those parts that would be allowed in // a batch request -- don't pass through other fancy fetch() @@ -720,7 +730,7 @@ export default class KintoClientBase { headers?: Record; } = {} ): Promise> { - const path = endpoint.permissions(); + const path = endpoints.permissions(); // Ensure the default sort parameter is something that exists in permissions // entries, as `last_modified` doesn't; here, we pick "id". const paginationOptions = { sort: "id", ...options }; @@ -752,7 +762,7 @@ export default class KintoClientBase { since?: string; } = {} ): Promise> { - const path = endpoint.bucket(); + const path = endpoints.bucket(); return this.paginatedList(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), @@ -783,7 +793,7 @@ export default class KintoClientBase { ): Promise> { const { data, permissions } = options; const _data = { ...data, id: id ? id : undefined }; - const path = _data.id ? endpoint.bucket(_data.id) : endpoint.bucket(); + const path = _data.id ? endpoints.bucket(_data.id) : endpoints.bucket(); return ( this.execute>( requests.createRequest( @@ -825,7 +835,7 @@ export default class KintoClientBase { if (!bucketObj.id) { throw new Error("A bucket id is required."); } - const path = endpoint.bucket(bucketObj.id); + const path = endpoints.bucket(bucketObj.id); const { last_modified } = { ...bucketObj, ...options }; return ( this.execute>( @@ -858,7 +868,7 @@ export default class KintoClientBase { last_modified?: number; } = {} ): Promise> { - const path = endpoint.bucket(); + const path = endpoints.bucket(); return ( this.execute>( requests.deleteRequest(path, { diff --git a/src/bucket.ts b/src/bucket.ts index ce0c0a7d..a066ff56 100644 --- a/src/bucket.ts +++ b/src/bucket.ts @@ -1,7 +1,6 @@ -import { toDataBody, isObject, capable, addEndpointOptions } from "./utils"; +import { toDataBody, isObject, capable } from "./utils"; import Collection from "./collection"; import * as requests from "./requests"; -import endpoint from "./endpoint"; import KintoClientBase, { PaginatedListParams, PaginationResult } from "./base"; import { KintoRequest, @@ -29,6 +28,7 @@ export interface BucketOptions { export default class Bucket { private client: KintoClientBase; public name: string; + private _endpoints: KintoClientBase["endpoints"]; private _retry: number; private _safe: boolean; private _headers: Record; @@ -57,6 +57,9 @@ export default class Bucket { * @type {String} */ this.name = name; + + this._endpoints = client.endpoints; + /** * @ignore */ @@ -145,7 +148,7 @@ export default class Bucket { retry?: number; } = {} ): Promise { - const path = endpoint.collection(this.name); + const path = this._endpoints.collection(this.name); const request: KintoRequest = { headers: this._getHeaders(options), path, @@ -174,7 +177,7 @@ export default class Bucket { retry?: number; } = {} ): Promise { - const path = endpoint.group(this.name); + const path = this._endpoints.group(this.name); const request: KintoRequest = { headers: this._getHeaders(options), path, @@ -210,8 +213,7 @@ export default class Bucket { retry?: number; } = {} ): Promise { - let path = endpoint.bucket(this.name); - path = addEndpointOptions(path, options); + const path = this._endpoints.bucket(this.name); const request = { headers: this._getHeaders(options), path, @@ -219,6 +221,8 @@ export default class Bucket { const { data } = (await this.client.execute(request, { retry: this._getRetry(options), + query: options.query, + fields: options.fields, })) as { data: T }; return data; } @@ -259,7 +263,7 @@ export default class Bucket { delete bucket.id; } - const path = endpoint.bucket(bucketId); + const path = this._endpoints.bucket(bucketId); const { patch, permissions } = options; const { last_modified } = { ...data, ...options }; const request = requests.updateRequest( @@ -295,7 +299,7 @@ export default class Bucket { retry?: number; } = {} ): Promise>> { - const path = endpoint.history(this.name); + const path = this._endpoints.history(this.name); return this.client.paginatedList>(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), @@ -322,7 +326,7 @@ export default class Bucket { fields?: string[]; } = {} ): Promise> { - const path = endpoint.collection(this.name); + const path = this._endpoints.collection(this.name); return this.client.paginatedList(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), @@ -354,7 +358,7 @@ export default class Bucket { ): Promise> { const { permissions, data = {} } = options; data.id = id; - const path = endpoint.collection(this.name, id); + const path = this._endpoints.collection(this.name, id); const request = requests.createRequest( path, { data, permissions }, @@ -397,7 +401,7 @@ export default class Bucket { } const { id } = collectionObj; const { last_modified } = { ...collectionObj, ...options }; - const path = endpoint.collection(this.name, id); + const path = this._endpoints.collection(this.name, id); const request = requests.deleteRequest(path, { last_modified, headers: this._getHeaders(options), @@ -430,7 +434,7 @@ export default class Bucket { fields?: string[]; } = {} ): Promise> { - const path = endpoint.group(this.name); + const path = this._endpoints.group(this.name); return this.client.paginatedList(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), @@ -461,8 +465,7 @@ export default class Bucket { fields?: string[]; } = {} ): Promise> { - let path = endpoint.group(this.name, id); - path = addEndpointOptions(path, options); + const path = this._endpoints.group(this.name, id); const request = { headers: this._getHeaders(options), path, @@ -470,6 +473,8 @@ export default class Bucket { return ( this.client.execute>(request, { retry: this._getRetry(options), + query: options.query, + fields: options.fields, }) as Promise> ); } @@ -504,7 +509,7 @@ export default class Bucket { id, members, }; - const path = endpoint.group(this.name, id); + const path = this._endpoints.group(this.name, id); const { permissions } = options; const request = requests.createRequest( path, @@ -557,7 +562,7 @@ export default class Bucket { ...options.data, ...group, }; - const path = endpoint.group(this.name, group.id); + const path = this._endpoints.group(this.name, group.id); const { patch, permissions } = options; const { last_modified } = { ...data, ...options }; const request = requests.updateRequest( @@ -601,7 +606,7 @@ export default class Bucket { const groupObj = toDataBody(group); const { id } = groupObj; const { last_modified } = { ...groupObj, ...options }; - const path = endpoint.group(this.name, id); + const path = this._endpoints.group(this.name, id); const request = requests.deleteRequest(path, { last_modified, headers: this._getHeaders(options), @@ -631,7 +636,7 @@ export default class Bucket { ): Promise<{ [key in Permission]?: string[] }> { const request = { headers: this._getHeaders(options), - path: endpoint.bucket(this.name), + path: this._endpoints.bucket(this.name), }; const { permissions } = (await this.client.execute(request, { @@ -664,7 +669,7 @@ export default class Bucket { if (!isObject(permissions)) { throw new Error("A permissions object is required."); } - const path = endpoint.bucket(this.name); + const path = this._endpoints.bucket(this.name); const { last_modified } = options; const data = { last_modified }; const request = requests.updateRequest( @@ -706,7 +711,7 @@ export default class Bucket { if (!isObject(permissions)) { throw new Error("A permissions object is required."); } - const path = endpoint.bucket(this.name); + const path = this._endpoints.bucket(this.name); const { last_modified } = options; const request = requests.jsonPatchPermissionsRequest( path, @@ -749,7 +754,7 @@ export default class Bucket { if (!isObject(permissions)) { throw new Error("A permissions object is required."); } - const path = endpoint.bucket(this.name); + const path = this._endpoints.bucket(this.name); const { last_modified } = options; const request = requests.jsonPatchPermissionsRequest( path, diff --git a/src/collection.ts b/src/collection.ts index 7d666507..92297f5d 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -2,8 +2,6 @@ import { v4 as uuid } from "uuid"; import { capable, toDataBody, isObject } from "./utils"; import * as requests from "./requests"; -import endpoint from "./endpoint"; -import { addEndpointOptions } from "./utils"; import KintoClientBase, { PaginatedListParams, PaginationResult } from "./base"; import Bucket from "./bucket"; import { @@ -34,6 +32,7 @@ export default class Collection { public client: KintoClientBase; private bucket: Bucket; public name: string; + private _endpoints: KintoClientBase["endpoints"]; private _retry: number; private _safe: boolean; private _headers: Record; @@ -71,6 +70,8 @@ export default class Collection { */ this.name = name; + this._endpoints = client.endpoints; + /** * @ignore */ @@ -133,7 +134,7 @@ export default class Collection { async getTotalRecords( options: { headers?: Record; retry?: number } = {} ): Promise { - const path = endpoint.record(this.bucket.name, this.name); + const path = this._endpoints.record(this.bucket.name, this.name); const request: KintoRequest = { headers: this._getHeaders(options), path, @@ -158,7 +159,7 @@ export default class Collection { async getRecordsTimestamp( options: { headers?: Record; retry?: number } = {} ): Promise { - const path = endpoint.record(this.bucket.name, this.name); + const path = this._endpoints.record(this.bucket.name, this.name); const request: KintoRequest = { headers: this._getHeaders(options), path, @@ -194,12 +195,13 @@ export default class Collection { retry?: number; } = {} ): Promise { - let path = endpoint.collection(this.bucket.name, this.name); - path = addEndpointOptions(path, options); + const path = this._endpoints.collection(this.bucket.name, this.name); const request = { headers: this._getHeaders(options), path }; const { data } = (await this.client.execute(request, { retry: this._getRetry(options), + query: options.query, + fields: options.fields, })) as { data: T }; return data; } @@ -233,7 +235,7 @@ export default class Collection { const { patch, permissions } = options; const { last_modified } = { ...data, ...options }; - const path = endpoint.collection(this.bucket.name, this.name); + const path = this._endpoints.collection(this.bucket.name, this.name); const request = requests.updateRequest( path, { data, permissions }, @@ -266,7 +268,7 @@ export default class Collection { retry?: number; } = {} ): Promise<{ [key in Permission]?: string[] }> { - const path = endpoint.collection(this.bucket.name, this.name); + const path = this._endpoints.collection(this.bucket.name, this.name); const request = { headers: this._getHeaders(options), path }; const { permissions } = (await this.client.execute(request, { @@ -299,7 +301,7 @@ export default class Collection { if (!isObject(permissions)) { throw new Error("A permissions object is required."); } - const path = endpoint.collection(this.bucket.name, this.name); + const path = this._endpoints.collection(this.bucket.name, this.name); const data = { last_modified: options.last_modified }; const request = requests.updateRequest( path, @@ -340,7 +342,7 @@ export default class Collection { if (!isObject(permissions)) { throw new Error("A permissions object is required."); } - const path = endpoint.collection(this.bucket.name, this.name); + const path = this._endpoints.collection(this.bucket.name, this.name); const { last_modified } = options; const request = requests.jsonPatchPermissionsRequest( path, @@ -383,7 +385,7 @@ export default class Collection { if (!isObject(permissions)) { throw new Error("A permissions object is required."); } - const path = endpoint.collection(this.bucket.name, this.name); + const path = this._endpoints.collection(this.bucket.name, this.name); const { last_modified } = options; const request = requests.jsonPatchPermissionsRequest( path, @@ -424,7 +426,7 @@ export default class Collection { } = {} ): Promise> { const { permissions } = options; - const path = endpoint.record(this.bucket.name, this.name, record.id); + const path = this._endpoints.record(this.bucket.name, this.name, record.id); const request = requests.createRequest( path, { data: record, permissions }, @@ -476,7 +478,7 @@ export default class Collection { > { const { permissions } = options; const id = record.id || uuid(); - const path = endpoint.attachment(this.bucket.name, this.name, id); + const path = this._endpoints.attachment(this.bucket.name, this.name, id); const { last_modified } = { ...record, ...options }; const addAttachmentRequest = requests.addAttachmentRequest( path, @@ -519,7 +521,11 @@ export default class Collection { } = {} ): Promise<{}> { const { last_modified } = options; - const path = endpoint.attachment(this.bucket.name, this.name, recordId); + const path = this._endpoints.attachment( + this.bucket.name, + this.name, + recordId + ); const request = requests.deleteRequest(path, { last_modified, headers: this._getHeaders(options), @@ -564,7 +570,7 @@ export default class Collection { } const { permissions } = options; const { last_modified } = { ...record, ...options }; - const path = endpoint.record(this.bucket.name, this.name, record.id); + const path = this._endpoints.record(this.bucket.name, this.name, record.id); const request = requests.updateRequest( path, { data: record, permissions }, @@ -609,7 +615,7 @@ export default class Collection { } const { id } = recordObj; const { last_modified } = { ...recordObj, ...options }; - const path = endpoint.record(this.bucket.name, this.name, id); + const path = this._endpoints.record(this.bucket.name, this.name, id); const request = requests.deleteRequest(path, { last_modified, headers: this._getHeaders(options), @@ -646,12 +652,13 @@ export default class Collection { retry?: number; } = {} ): Promise> { - let path = endpoint.record(this.bucket.name, this.name, id); - path = addEndpointOptions(path, options); + const path = this._endpoints.record(this.bucket.name, this.name, id); const request = { headers: this._getHeaders(options), path }; return ( this.client.execute>(request, { retry: this._getRetry(options), + query: options.query, + fields: options.fields, }) as Promise> ); } @@ -699,7 +706,7 @@ export default class Collection { at?: number; } = {} ): Promise> { - const path = endpoint.record(this.bucket.name, this.name); + const path = this._endpoints.record(this.bucket.name, this.name); if (options.at) { return this.getSnapshot(options.at); } else { diff --git a/src/endpoint.ts b/src/endpoints.ts similarity index 100% rename from src/endpoint.ts rename to src/endpoints.ts diff --git a/test/bucket_test.ts b/test/bucket_test.ts index 9bd24a78..5f704a75 100644 --- a/test/bucket_test.ts +++ b/test/bucket_test.ts @@ -5,17 +5,13 @@ import Bucket, { BucketOptions } from "../src/bucket"; import Collection from "../src/collection"; import * as requests from "../src/requests"; import { PaginationResult } from "../src/base"; -import { Stub, expectAsyncError } from "./test_utils"; +import { Stub, expectAsyncError, fakeHeaders } from "./test_utils"; chai.should(); chai.config.includeStack = true; const FAKE_SERVER_URL = "http://fake-server/v1"; -const fakeHeaders = { - get: () => "", -}; - /** @test {Bucket} */ describe("Bucket", () => { let sandbox: sinon.SinonSandbox, client: KintoClient; @@ -47,7 +43,7 @@ describe("Bucket", () => { it("should execute expected request", async () => { const executeStub = sandbox .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + .returns(Promise.resolve({ headers: fakeHeaders() })); await getBlogBucket().getData(); @@ -69,16 +65,23 @@ describe("Bucket", () => { it("should support query and fields", () => { const response = { data: { foo: "bar" }, permissions: {} }; - const executeStub = sandbox - .stub(client, "execute") - .returns(Promise.resolve(response)); + const requestStub = sandbox.stub(client.http, "request").returns( + Promise.resolve({ + headers: fakeHeaders(), + json: response, + status: 200, + }) + ); getBlogBucket().getData({ query: { a: "b" }, fields: ["c", "d"] }); - sinon.assert.calledWithMatch(executeStub, { - path: "/buckets/blog?a=b&_fields=c,d", - headers: {}, - }); + sinon.assert.calledWithMatch( + requestStub, + "http://fake-server/v1/buckets/blog?a=b&_fields=c,d", + { + headers: {}, + } + ); }); }); @@ -156,7 +159,7 @@ describe("Bucket", () => { it("should execute expected request", async () => { const executeStub = sandbox .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + .returns(Promise.resolve({ headers: fakeHeaders() })); await getBlogBucket().getCollectionsTimestamp(); @@ -418,7 +421,7 @@ describe("Bucket", () => { it("should execute expected request", async () => { const executeStub = sandbox .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + .returns(Promise.resolve({ headers: fakeHeaders() })); await getBlogBucket().getGroupsTimestamp(); @@ -512,13 +515,11 @@ describe("Bucket", () => { const fakeGroup = { data: {}, permissions: {} }; let executeStub: Stub; - beforeEach(() => { + it("should extend request headers with optional ones", () => { executeStub = sandbox .stub(client, "execute") .returns(Promise.resolve(fakeGroup)); - }); - it("should extend request headers with optional ones", () => { getBlogBucket({ headers: { Foo: "Bar" }, }).getGroup("foo", { headers: { Baz: "Qux" } }); @@ -530,19 +531,34 @@ describe("Bucket", () => { }); it("should return the group", async () => { + executeStub = sandbox + .stub(client, "execute") + .returns(Promise.resolve(fakeGroup)); + (await getBlogBucket().getGroup("foo")).should.deep.equal(fakeGroup); }); it("should support query and fields", () => { + const requestStub = sandbox.stub(client.http, "request").returns( + Promise.resolve({ + headers: fakeHeaders(), + json: {}, + status: 200, + }) + ); + getBlogBucket().getGroup("foo", { query: { a: "b" }, fields: ["c", "d"], }); - sinon.assert.calledWithMatch(executeStub, { - path: "/buckets/blog/groups/foo?a=b&_fields=c,d", - headers: {}, - }); + sinon.assert.calledWithMatch( + requestStub, + "http://fake-server/v1/buckets/blog/groups/foo?a=b&_fields=c,d", + { + headers: {}, + } + ); }); }); diff --git a/test/collection_test.ts b/test/collection_test.ts index f016f6be..1a734287 100644 --- a/test/collection_test.ts +++ b/test/collection_test.ts @@ -4,7 +4,12 @@ import KintoClient from "../src"; import Bucket from "../src/bucket"; import Collection, { CollectionOptions } from "../src/collection"; import * as requests from "../src/requests"; -import { fakeServerResponse, Stub, expectAsyncError } from "./test_utils"; +import { + fakeServerResponse, + Stub, + expectAsyncError, + fakeHeaders, +} from "./test_utils"; import { PaginationResult } from "../src/base"; chai.should(); @@ -27,10 +32,6 @@ describe("Collection", () => { sandbox.restore(); }); - const fakeHeaders = { - get: () => "", - }; - function getBlogPostsCollection(options?: CollectionOptions) { return new Bucket(client, "blog").collection("posts", options); } @@ -40,7 +41,7 @@ describe("Collection", () => { it("should execute expected request", async () => { const executeStub = sandbox .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + .returns(Promise.resolve({ headers: fakeHeaders() })); await getBlogPostsCollection().getTotalRecords(); @@ -75,7 +76,7 @@ describe("Collection", () => { it("should execute expected request", async () => { const executeStub = sandbox .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + .returns(Promise.resolve({ headers: fakeHeaders() })); await getBlogPostsCollection().getData(); @@ -100,29 +101,43 @@ describe("Collection", () => { }); it("should pass query through", async () => { - const executeStub = sandbox - .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + const requestStub = sandbox.stub(client.http, "request").returns( + Promise.resolve({ + headers: fakeHeaders(), + json: {}, + status: 200, + }) + ); await getBlogPostsCollection().getData({ query: { _expected: '"123"' } }); - sinon.assert.calledWithMatch(executeStub, { - path: "/buckets/blog/collections/posts?_expected=%22123%22", - headers: {}, - }); + sinon.assert.calledWithMatch( + requestStub, + "http://fake-server/v1/buckets/blog/collections/posts?_expected=%22123%22", + { + headers: {}, + } + ); }); it("supports _fields", async () => { - const executeStub = sandbox - .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + const requestStub = sandbox.stub(client.http, "request").returns( + Promise.resolve({ + headers: fakeHeaders(), + json: {}, + status: 200, + }) + ); await getBlogPostsCollection().getData({ fields: ["a", "b"] }); - sinon.assert.calledWithMatch(executeStub, { - path: "/buckets/blog/collections/posts?_fields=a,b", - headers: {}, - }); + sinon.assert.calledWithMatch( + requestStub, + "http://fake-server/v1/buckets/blog/collections/posts?_fields=a,b", + { + headers: {}, + } + ); }); }); @@ -528,10 +543,14 @@ describe("Collection", () => { it("should support query and fields", () => { coll.getRecord("1", { query: { a: "b" }, fields: ["c", "d"] }); - sinon.assert.calledWith(executeStub, { - headers: { Baz: "Qux", Foo: "Bar" }, - path: "/buckets/blog/collections/posts/records/1?a=b&_fields=c,d", - }); + sinon.assert.calledWith( + executeStub, + { + headers: { Baz: "Qux", Foo: "Bar" }, + path: "/buckets/blog/collections/posts/records/1", + }, + { fields: ["c", "d"], query: { a: "b" }, retry: 0 } + ); }); }); @@ -540,7 +559,7 @@ describe("Collection", () => { it("should execute expected request", async () => { const executeStub = sandbox .stub(client, "execute") - .returns(Promise.resolve({ headers: fakeHeaders })); + .returns(Promise.resolve({ headers: fakeHeaders() })); await getBlogPostsCollection().getRecordsTimestamp(); diff --git a/test/endpoint_test.ts b/test/endpoint_test.ts index 6ed677e0..a27554e1 100644 --- a/test/endpoint_test.ts +++ b/test/endpoint_test.ts @@ -1,6 +1,6 @@ import chai, { expect } from "chai"; -import endpoint from "../src/endpoint"; +import endpoints from "../src/endpoints"; chai.should(); chai.config.includeStack = true; @@ -8,36 +8,36 @@ chai.config.includeStack = true; /** @test {endpoint} */ describe("endpoint()", () => { it("should provide a root endpoint", () => { - expect(endpoint.root()).eql("/"); + expect(endpoints.root()).eql("/"); }); it("should provide a batch endpoint", () => { - expect(endpoint.batch()).eql("/batch"); + expect(endpoints.batch()).eql("/batch"); }); it("should provide a bucket endpoint", () => { - expect(endpoint.bucket("foo")).eql("/buckets/foo"); + expect(endpoints.bucket("foo")).eql("/buckets/foo"); }); it("should provide a collection endpoint", () => { - expect(endpoint.collection("foo", "bar")).eql( + expect(endpoints.collection("foo", "bar")).eql( "/buckets/foo/collections/bar" ); }); it("should provide a records endpoint", () => { - expect(endpoint.record("foo", "bar")).eql( + expect(endpoints.record("foo", "bar")).eql( "/buckets/foo/collections/bar/records" ); }); it("should provide a record endpoint", () => { - expect(endpoint.record("foo", "bar", "42")).eql( + expect(endpoints.record("foo", "bar", "42")).eql( "/buckets/foo/collections/bar/records/42" ); }); it("should provide a permissions endpoint", () => { - expect(endpoint.permissions()).eql("/permissions"); + expect(endpoints.permissions()).eql("/permissions"); }); }); diff --git a/test/http_test.ts b/test/http_test.ts index f1aa1ce5..a6c93238 100644 --- a/test/http_test.ts +++ b/test/http_test.ts @@ -128,7 +128,7 @@ describe("HTTP class", () => { it("should resolve with headers", async () => { const { headers } = await http.request("/"); - headers.get("b")!.should.equal(2); + headers.get("b")!.should.equal("2"); }); }); diff --git a/test/test_utils.ts b/test/test_utils.ts index 5789bf07..a0128baa 100644 --- a/test/test_utils.ts +++ b/test/test_utils.ts @@ -1,21 +1,24 @@ import sinon from "sinon"; import { expect } from "chai"; +export function fakeHeaders(headers: { [key: string]: string | number } = {}) { + const h = new Headers(); + Object.entries(headers).forEach(([k, v]) => h.set(k, v.toString())); + return h; +} + export function fakeServerResponse( status: number, json: any, headers: { [key: string]: string | number } = {} ) { + const respHeaders = fakeHeaders(headers); + if (!respHeaders.has("Content-Length")) { + respHeaders.set("Content-Length", JSON.stringify(json).length.toString()); + } return Promise.resolve({ status: status, - headers: { - get(name: string) { - if (!("Content-Length" in headers) && name === "Content-Length") { - return JSON.stringify(json).length; - } - return headers[name]; - }, - }, + headers: respHeaders, text() { return Promise.resolve(JSON.stringify(json)); },