From 500600d3e9a98ff5a9ed6e3ab1e45aeea27e8bf2 Mon Sep 17 00:00:00 2001 From: Luis Ball Date: Wed, 2 Mar 2022 15:43:05 -0800 Subject: [PATCH] feat: add absolute url support This commit adds type definitions, tests, and the necessary js-core RC to enable absolute URL support in vue-imgix. The srcsset generation tests need to be updated to properly mock the static methods. Co-authored-by: Sherwin Heydarbeygi --- package.json | 2 +- src/App.vue | 6 +-- src/components/simple/static-api.vue | 15 +++--- src/plugins/vue-imgix/types.ts | 2 + src/plugins/vue-imgix/vue-imgix.ts | 12 ++--- tests/e2e/specs/static-api.spec.js | 17 ++++++ tests/unit/build-src-set.spec.ts | 79 +++++++++++++++++++++++++++- tests/unit/build-url.spec.ts | 15 ++++-- yarn.lock | 24 +++++---- 9 files changed, 140 insertions(+), 32 deletions(-) create mode 100644 tests/e2e/specs/static-api.spec.js diff --git a/package.json b/package.json index 460d9c09..8a42323c 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "release:dryRun": "npx node-env-run --exec 'npx semantic-release --dryRun'" }, "dependencies": { - "@imgix/js-core": "^3.1.3" + "@imgix/js-core": "^3.6.0-rc.1" }, "devDependencies": { "@babel/core": "^7.6.14", diff --git a/src/App.vue b/src/App.vue index 7a712f2a..44ca56c7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,7 +3,7 @@

Simple Usage

Static Usage

- +

Advanced Usage

@@ -22,7 +22,7 @@ import advancedBuildUrl from './components/advanced/buildUrl'; import advancedBuildSrcSet from './components/advanced/buildSrcSet'; import advancedApi from './components/advanced/advanced'; import simple from './components/simple/simple'; -import partial from './components/simple/static-api'; +import staticApi from './components/simple/static-api'; export default { name: 'App', @@ -33,7 +33,7 @@ export default { advancedBuildSrcSet, advancedApi, simple, - partial, + staticApi, }, computed: {}, diff --git a/src/components/simple/static-api.vue b/src/components/simple/static-api.vue index 303156f2..b74d144c 100644 --- a/src/components/simple/static-api.vue +++ b/src/components/simple/static-api.vue @@ -1,26 +1,23 @@ diff --git a/src/plugins/vue-imgix/types.ts b/src/plugins/vue-imgix/types.ts index 32ba399a..e5163b4b 100644 --- a/src/plugins/vue-imgix/types.ts +++ b/src/plugins/vue-imgix/types.ts @@ -33,7 +33,9 @@ export type IBuildSrcSet = ( export type IVueImgixClient = { buildUrlObject: IBuildUrlObject; buildUrl: IBuildUrl; + _buildUrl: IBuildUrl; buildSrcSet: IBuildSrcSet; + _buildSrcSet: IBuildSrcSet; }; export type IVueUseImgixOptions = IImgixClientOptions; diff --git a/src/plugins/vue-imgix/vue-imgix.ts b/src/plugins/vue-imgix/vue-imgix.ts index 623c245f..b926daeb 100644 --- a/src/plugins/vue-imgix/vue-imgix.ts +++ b/src/plugins/vue-imgix/vue-imgix.ts @@ -1,5 +1,6 @@ import ImgixClient from '@imgix/js-core'; import { IxImg } from './ix-img'; +import type { IVueImgixClient } from './types'; import { IBuildSrcSet, IBuildSrcSetOptions, @@ -8,9 +9,8 @@ import { IBuildUrlObjectOptions, IBuildUrlObjectResult, IImgixClientOptions, - IImgixParams, + IImgixParams } from './types'; -import type { IVueImgixClient } from './types'; // Do not change this const VERSION = '3.0.0-rc.1'; @@ -78,7 +78,7 @@ class VueImgixClient implements IVueImgixClient { if (!url.includes('://')) { return this.client.buildURL(url, this.buildIxParams(ixParams)); } else { - return ImgixClient._buildURL({ url, params: this.buildIxParams(ixParams) }); + return ImgixClient._buildURL(url, this.buildIxParams(ixParams) ); } }; @@ -109,11 +109,11 @@ class VueImgixClient implements IVueImgixClient { options, ); } else { - return ImgixClient._buildSrcSet({ + return ImgixClient._buildSrcSet( url, - params: this.buildIxParams(ixParams), + this.buildIxParams(ixParams), options, - }); + ); } }; } diff --git a/tests/e2e/specs/static-api.spec.js b/tests/e2e/specs/static-api.spec.js new file mode 100644 index 00000000..e769b956 --- /dev/null +++ b/tests/e2e/specs/static-api.spec.js @@ -0,0 +1,17 @@ +describe('Static API', () => { + it('should render image with relative URL', () => { + cy.visit('/'); + cy.findByTestId('static-api-relative').should(($image) => { + expect($image.attr('src')).to.match(/assets.imgix.net/); + expect($image.attr('srcset')).to.match(/assets.imgix.net/); + }); + }) + it('should render image with an absolute URL', () => { + cy.visit('/'); + cy.findByTestId('static-api-absolute').should(($image) => { + expect($image.attr('src')).to.match(/https:\/\/sdk-test.imgix.net\/amsterdam.jpg/, + ); + expect($image.attr('srcset')).to.match(/sdk-test.imgix.net\/amsterdam.jpg/); + }); + }) +}); diff --git a/tests/unit/build-src-set.spec.ts b/tests/unit/build-src-set.spec.ts index 638cef5c..d77e9094 100644 --- a/tests/unit/build-src-set.spec.ts +++ b/tests/unit/build-src-set.spec.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ import { buildImgixClient, - IVueImgixClient, + IVueImgixClient } from '@/plugins/vue-imgix/vue-imgix'; describe('buildSrcSet', () => { @@ -79,3 +79,80 @@ describe('buildSrcSet', () => { }); }); }); + +describe('_buildSrcSet', () => { + let client: IVueImgixClient; + beforeAll(() => { + client = buildImgixClient({ + domain: 'assets.imgix.net', + }); + }); + + it('builds an srcset list', () => { + const url = client._buildSrcSet('https://sdk-test.imgix.net/amsterdam.jpg', {}); + + const firstSrcSet = url.split(',')[0].split(' '); + expect(firstSrcSet[0]).toMatch(/sdk-test.imgix.net\/amsterdam.jpg/); + expect(firstSrcSet[0]).toMatch(/w=[0-9]/); + expect(firstSrcSet[1]).toMatch(/^[0-9]+w$/); + }); + + // TODO: fix these tests + describe.skip('srcset generation', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let mockImgixClient: any; + let vueImgixClient: IVueImgixClient; + beforeEach(() => { + jest.resetModules(); + jest.mock('@imgix/js-core'); + const { buildImgixClient } = require('@/plugins/vue-imgix/'); + const ImgixClient = require('@imgix/js-core'); + mockImgixClient = { + settings: {}, + _buildSrcSet: jest.fn(), + _buildURL: jest.fn(), + }; + ImgixClient.mockImplementation(() => mockImgixClient); + vueImgixClient = buildImgixClient({ + domain: 'testing.imgix.net', + }); + }); + afterAll(() => { + jest.resetAllMocks(); + jest.resetModules(); + }); + it('custom widths are passed to @imgix/js-core', () => { + vueImgixClient._buildSrcSet('https://sdk-test.imgix.net/amsterdam.jpg', {}, { widths: [100, 200] }); + + expect(mockImgixClient._buildSrcSet).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.objectContaining({ + widths: [100, 200], + }), + ); + }); + it('a custom width tolerance is passed to @imgix/js-core', () => { + vueImgixClient._buildSrcSet('https://sdk-test.imgix.net/amsterdam.jpg', {}, { widthTolerance: 0.2 }); + + expect(mockImgixClient._buildSrcSet).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.objectContaining({ widthTolerance: 0.2 }), + ); + }); + it('custom min/max widths are passed to @imgix/js-core', () => { + vueImgixClient._buildSrcSet( + 'https://sdk-test.imgix.net/amsterdam.jpg', + {}, + { minWidth: 500, maxWidth: 2000 }, + ); + + expect(mockImgixClient._buildSrcSet).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.objectContaining({ minWidth: 500, maxWidth: 2000 }), + ); + }); + }); +}); diff --git a/tests/unit/build-url.spec.ts b/tests/unit/build-url.spec.ts index 1544be6c..852e56a5 100644 --- a/tests/unit/build-url.spec.ts +++ b/tests/unit/build-url.spec.ts @@ -1,6 +1,6 @@ import { - buildImgixClient, - IVueImgixClient, + buildImgixClient, + IVueImgixClient } from '@/plugins/vue-imgix/vue-imgix'; describe('buildUrl', () => { @@ -11,8 +11,17 @@ describe('buildUrl', () => { }); }); - it('builds an imgix url', () => { + it('should build an imgix url', () => { const url = client.buildUrl('/examples/pione.jpg', {}); expect(url).toMatch(/assets.imgix.net\/examples\/pione.jpg/); }); + + it('should accept absolute URLs', () => { + let customUrl = client._buildUrl( + 'https://sdk-test.imgix.net/amsterdam.jpg', + {}, + ); + + expect(customUrl).toMatch(/https:\/\/sdk-test.imgix.net\/amsterdam.jpg/); + }); }); diff --git a/yarn.lock b/yarn.lock index 79431163..745623b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1435,13 +1435,14 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@imgix/js-core@^3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@imgix/js-core/-/js-core-3.1.3.tgz#9c26366f84f59e6c238c41455f45aacdf04862b7" - integrity sha512-7HUIFy4dq9wLSJURgPhglSni50rt3af4cAyBip14koR5oPIGgTGs0W41aQZc5gyCesh7jZaSjm4VxiwqS7gszw== +"@imgix/js-core@^3.6.0-rc.1": + version "3.6.0-rc.1" + resolved "https://registry.yarnpkg.com/@imgix/js-core/-/js-core-3.6.0-rc.1.tgz#483b0aaf857186a4fba34b0bc7d995af5f871108" + integrity sha512-k0kSoZiVjHKFxgz/IFvW6KUH/SE4CZfT6huFmT2hU9RhFmZczXfk0ND6PzrElvFzmchrPLsGdgS9NdjWxmgUlg== dependencies: - js-base64 "~2.6.0" + js-base64 "~3.7.0" md5 "^2.2.1" + ufo "^0.7.10" "@intervolga/optimize-cssnano-plugin@^1.0.5": version "1.0.6" @@ -8567,10 +8568,10 @@ joi@^17.4.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" -js-base64@~2.6.0: - version "2.6.4" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" - integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== +js-base64@~3.7.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.2.tgz#816d11d81a8aff241603d19ce5761e13e41d7745" + integrity sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ== js-beautify@^1.6.12: version "1.11.0" @@ -12898,6 +12899,11 @@ typescript@~4.1.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.6.tgz#1becd85d77567c3c741172339e93ce2e69932138" integrity sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow== +ufo@^0.7.10: + version "0.7.11" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.7.11.tgz#17defad497981290383c5d26357773431fdbadcb" + integrity sha512-IT3q0lPvtkqQ8toHQN/BkOi4VIqoqheqM1FnkNWT9y0G8B3xJhwnoKBu5OHx8zHDOvveQzfKuFowJ0VSARiIDg== + uglify-js@3.4.x: version "3.4.10" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"