From bc0b5446ce7769480b3e31b9f849156e31c43e4b Mon Sep 17 00:00:00 2001 From: sloranger Date: Tue, 17 Mar 2020 17:40:18 -0400 Subject: [PATCH] Add fetchOne function from url and options that doesn't require an id --- lib/mixins/http.js | 8 +++++ test/mixins/http.js | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/lib/mixins/http.js b/lib/mixins/http.js index 78f2704..2f4a511 100755 --- a/lib/mixins/http.js +++ b/lib/mixins/http.js @@ -31,6 +31,14 @@ const mixin = (superclass) => class extends superclass { return model.fetch(options).then(() => model); } + static fetchOneFromUrlAndOptions({ url, options = {} } = {}) { + const Model = this; + + return this.sync({ method: 'get', url, options }).then((resp) => { + return new Model(nullToUndefined(resp.data)); + }); + } + static sync({ method, url, options }) { return sync({ method, url, options }); } diff --git a/test/mixins/http.js b/test/mixins/http.js index ca830f8..4e66bbd 100755 --- a/test/mixins/http.js +++ b/test/mixins/http.js @@ -224,6 +224,78 @@ describe('Http', () => { }); }); + describe('.fetchOneFromUrlAndOptions', () => { + const defaultValue = 'Mitaine'; + let KlassWithAttributes, id, url, data, httpOptions, result; + + function configureHttpMock() { + httpMock().onGet(url, httpOptions).reply(() => { + return [200, data]; + }); + } + + beforeEach(async() => { + id = Math.random(); + url = `${urlRoot}/${urlResource}/${id}`; + data = { + stuff: Math.random(), + }; + + KlassWithAttributes = class extends Klass { + buildFields() { return { id: new Attribute(), stuff: new Attribute({ value: defaultValue }) }; } + }; + }); + + context('when data is undefined', () => { + beforeEach(async() => { + configureHttpMock(); + data = undefined; + result = await KlassWithAttributes.fetchOneFromUrlAndOptions({ url }); + }); + + it('should return an instance of model class', () => { + expect(result).to.be.instanceOf(KlassWithAttributes); + }); + + it('should return data with default value', async() => { + expect(result.fields.stuff.value).to.equal(defaultValue); + }); + }); + + context('when data is null', () => { + beforeEach(async() => { + configureHttpMock(); + data = undefined; + result = await KlassWithAttributes.fetchOneFromUrlAndOptions({ url }); + }); + + it('should return an instance of model class', () => { + expect(result).to.be.instanceOf(KlassWithAttributes); + }); + + it('should return data with default value', async() => { + expect(result.fields.stuff.value).to.equal(defaultValue); + }); + }); + + context('with options', () => { + beforeEach(async() => { + httpOptions = { params: { stuff: Math.random() } }; + configureHttpMock(); + + result = await KlassWithAttributes.fetchOneFromUrlAndOptions({ url, options: httpOptions }); + }); + + it('should return an instance of model class', () => { + expect(result).to.be.instanceOf(KlassWithAttributes); + }); + + it('should retrieve data according to specified url and options', async() => { + expect(result.fields.stuff.value).to.equal(data.stuff); + }); + }); + }); + describe('#buildUrl', () => { describe('when id is the primary key', () => { let KlassWithAttributes;