diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index cadf225..a02a5cd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -27,4 +27,4 @@ If applicable, add screenshots to help explain your problem. ### Additional Context -Add any other context about the problem here. \ No newline at end of file +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/chore.md b/.github/ISSUE_TEMPLATE/chore.md index 91bd046..12f9f03 100644 --- a/.github/ISSUE_TEMPLATE/chore.md +++ b/.github/ISSUE_TEMPLATE/chore.md @@ -16,4 +16,4 @@ What specific changes are needed? ### Additional Notes -Add any other relevant information here. \ No newline at end of file +Add any other relevant information here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 9a78d2d..7576fd7 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ blank_issues_enabled: false contact_links: - name: Screenly Zapier Integration - url: https://developer.screenly.io/api_v4_1/ \ No newline at end of file + url: https://developer.screenly.io/api_v4_1/ diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ed14d8b..540bac0 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -20,4 +20,4 @@ A clear and concise description of any alternative solutions or features you've ### Additional Context -Add any other context or screenshots about the feature request here. \ No newline at end of file +Add any other context or screenshots about the feature request here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2b94971..e35a93f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,9 +2,9 @@ Please include a summary of the changes and which issue is fixed. Please also include relevant motivation and context. -* Fixes #(issue-1) -* Fixes #(issue-2) -* Fixes #(issue-n) +- Fixes #(issue-1) +- Fixes #(issue-2) +- Fixes #(issue-n) ### How Has This Been Tested? @@ -22,4 +22,4 @@ Please describe the tests that you ran to verify your changes. Provide instructi ### Screenshots -If applicable, add screenshots to help explain your changes. \ No newline at end of file +If applicable, add screenshots to help explain your changes. diff --git a/.github/workflows/check-workflow-syntax.yml b/.github/workflows/check-workflow-syntax.yml index bf11b0b..aab4208 100644 --- a/.github/workflows/check-workflow-syntax.yml +++ b/.github/workflows/check-workflow-syntax.yml @@ -1,4 +1,3 @@ - name: Check GitHub Actions Workflow Syntax on: diff --git a/.husky/pre-commit b/.husky/pre-commit index 72c4429..19c5b86 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1,2 @@ npm test +npx prettier --check . diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3576d06..04a9ea5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,11 +27,13 @@ Thank you for your interest in contributing to the Screenly Zapier Integration! ## Development Workflow 1. Create a new branch for your feature/fix: + ```bash git checkout -b feature/your-feature-name ``` 1. Make your changes and ensure: + - All tests pass: `npm test` - Code is properly linted: `npm run lint` - Security audit passes: `npm audit` diff --git a/actions/cleanup-zapier-content.js b/actions/cleanup-zapier-content.js index a1a24c5..8fc180d 100644 --- a/actions/cleanup-zapier-content.js +++ b/actions/cleanup-zapier-content.js @@ -28,10 +28,10 @@ const cleanupZapierContent = { // Get all playlists associated with the Zapier tag const playlistToLabelMappings = await utils.getPlaylistsByLabel(z, bundle, { - labelId: label.id + labelId: label.id, }); - const playListIds = playlistToLabelMappings.map(mapping => mapping.playlist_id); + const playListIds = playlistToLabelMappings.map((mapping) => mapping.playlist_id); let successfulDeletions = 0; // Delete each playlist diff --git a/actions/complete-workflow.js b/actions/complete-workflow.js index c2bbdc3..34806c6 100644 --- a/actions/complete-workflow.js +++ b/actions/complete-workflow.js @@ -81,8 +81,8 @@ const completeWorkflow = { const labelQueryResponse = await z.request({ url: `https://api.screenlyapp.com/api/v4/labels?name=eq.${ZAPIER_TAG}`, headers: { - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, }); @@ -97,8 +97,8 @@ const completeWorkflow = { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, body: { name: ZAPIER_TAG, diff --git a/constants.js b/constants.js index 6e7f2e9..1e7b0c9 100644 --- a/constants.js +++ b/constants.js @@ -1,4 +1,4 @@ module.exports = { ZAPIER_TAG: 'created_by_zapier', READY_STATES: ['downloading', 'processing', 'finished'], -}; \ No newline at end of file +}; diff --git a/docs/common-use-cases.md b/docs/common-use-cases.md index 085eda0..753864a 100644 --- a/docs/common-use-cases.md +++ b/docs/common-use-cases.md @@ -45,6 +45,7 @@ - Disable rain-specific promotions ### Setup Steps: + 1. Create weather-specific playlists in Screenly: - "Summer Treats" - cold items - "Winter Warmers" - hot items @@ -63,4 +64,4 @@ - Increase sales with contextual promotions - Show relevant products at the right time - Create urgency with weather-specific offers -- No manual playlist management needed \ No newline at end of file +- No manual playlist management needed diff --git a/docs/cookbook/README.md b/docs/cookbook/README.md index b95d2e9..27511eb 100644 --- a/docs/cookbook/README.md +++ b/docs/cookbook/README.md @@ -4,5 +4,5 @@ This documentation is a collection of how-to guides for using the Screenly integ ## Quick Links -* [Uploading an Asset via Google Drive](uploading-an-asset-via-google-drive.md) -* [Uploading an Asset via Dropbox](uploading-an-asset-via-dropbox.md) \ No newline at end of file +- [Uploading an Asset via Google Drive](uploading-an-asset-via-google-drive.md) +- [Uploading an Asset via Dropbox](uploading-an-asset-via-dropbox.md) diff --git a/docs/cookbook/uploading-an-asset-via-dropbox.md b/docs/cookbook/uploading-an-asset-via-dropbox.md index 1ba0871..d49396d 100644 --- a/docs/cookbook/uploading-an-asset-via-dropbox.md +++ b/docs/cookbook/uploading-an-asset-via-dropbox.md @@ -10,41 +10,45 @@ Click **New Zap** from the dropdown menu. You will be redirected to the Zap edit Click the **Trigger** button. In the modal that appears, search for and select **Dropbox**. During setup, you'll need to configure: -* **Trigger Event**: Select **New File in Folder** -* **Account**: Click **Sign In** and authenticate with your Dropbox account. When prompted, allow Zapier to access your Dropbox files. -* Click **Continue** + +- **Trigger Event**: Select **New File in Folder** +- **Account**: Click **Sign In** and authenticate with your Dropbox account. When prompted, allow Zapier to access your Dropbox files. +- Click **Continue** ![Dropbox trigger setup](/docs/cookbook/images/zapier-dropbox-01-trigger-setup.png) For configuration: -* Select the **Space** and **Folder** you want to monitor. -* Select **False** for **Include files in subfolders?** -* Keep **Include file contents?** set to **Yes** -* Keep **Include sharing link?** set to **Yes** -* Click **Continue** -* Click **Test Trigger** (or **Skip Test** to proceed without testing) + +- Select the **Space** and **Folder** you want to monitor. +- Select **False** for **Include files in subfolders?** +- Keep **Include file contents?** set to **Yes** +- Keep **Include sharing link?** set to **Yes** +- Click **Continue** +- Click **Test Trigger** (or **Skip Test** to proceed without testing) ![Dropbox trigger configuration](/docs/cookbook/images/zapier-dropbox-02-trigger-configure.png) ## Step 3 — Select The Action Event -* Click the **Action** button -* Search for and select **Screenly (x.y.z)** -* For **Action Event**, select **Upload Asset** +- Click the **Action** button +- Search for and select **Screenly (x.y.z)** +- For **Action Event**, select **Upload Asset** For **Account**: -* Click **Sign In** -* In the new window, enter your Screenly API key -* Click **Yes, Continue to Screenly (x.y.z)** -* Click **Continue** + +- Click **Sign In** +- In the new window, enter your Screenly API key +- Click **Yes, Continue to Screenly (x.y.z)** +- Click **Continue** ![Screenly action setup](/docs/cookbook/images/zapier-dropbox-03-action-setup.png) Configure the action: -* For **File URL**: Click **+** and select **Link** -* For **Title**: Click **+** and select **File Name** -* Click **Continue** -* Click **Test Step** (or **Skip Test** to proceed without testing) + +- For **File URL**: Click **+** and select **Link** +- For **Title**: Click **+** and select **File Name** +- Click **Continue** +- Click **Test Step** (or **Skip Test** to proceed without testing) ![Screenly action configuration](/docs/cookbook/images/zapier-dropbox-04-action-configure.png) @@ -55,11 +59,11 @@ using the toggle switch. ## Step 5 — Test Your Zap -* Upload a file to your selected Dropbox folder -* Wait a few minutes for processing -* Visit [screenly.io](https://www.screenly.io/) and sign in -* Click **Content** in the menu bar -* Verify that your new asset appears +- Upload a file to your selected Dropbox folder +- Wait a few minutes for processing +- Visit [screenly.io](https://www.screenly.io/) and sign in +- Click **Content** in the menu bar +- Verify that your new asset appears You can monitor the Zap's execution in the [Zap history](https://zapier.com/app/history). diff --git a/docs/cookbook/uploading-an-asset-via-google-drive.md b/docs/cookbook/uploading-an-asset-via-google-drive.md index 41a7630..a2ca852 100644 --- a/docs/cookbook/uploading-an-asset-via-google-drive.md +++ b/docs/cookbook/uploading-an-asset-via-google-drive.md @@ -10,39 +10,43 @@ Click **New Zap** from the dropdown menu. You will be redirected to the Zap edit Click the **Trigger** button. In the modal that appears, search for and select **Google Drive**. During setup, you'll need to configure: -* **Trigger Event**: Select **New File in Folder** -* **Account**: Click **Sign In** and authenticate with your preferred Google account. + +- **Trigger Event**: Select **New File in Folder** +- **Account**: Click **Sign In** and authenticate with your preferred Google account. When prompted, allow Zapier to access your Google Drive. -* Click **Continue** +- Click **Continue** ![Google Drive trigger setup](/docs/cookbook/images/zapier-google-drive-01-trigger-setup.png) For configuration: -* Select the **Drive** and **Folder** you want to monitor -* Click **Continue** -* Click **Test Trigger** (or **Skip Test** to proceed without testing) + +- Select the **Drive** and **Folder** you want to monitor +- Click **Continue** +- Click **Test Trigger** (or **Skip Test** to proceed without testing) ![Google Drive trigger configuration](/docs/cookbook/images/zapier-google-drive-02-trigger-configure.png) ## Step 3 — Select The Action Event -* Click the **Action** button -* Search for and select **Screenly (x.y.z)** -* For **Action Event**, select **Upload Asset** +- Click the **Action** button +- Search for and select **Screenly (x.y.z)** +- For **Action Event**, select **Upload Asset** For **Account**: -* Click **Sign In** -* In the new window, enter your Screenly API key -* Click **Yes, Continue to Screenly (x.y.z)** -* Click **Continue** + +- Click **Sign In** +- In the new window, enter your Screenly API key +- Click **Yes, Continue to Screenly (x.y.z)** +- Click **Continue** ![Screenly action setup](/docs/cookbook/images/zapier-google-drive-03-action-setup.png) Configure the action: -* For **File URL**: Click **+** and select **File** -* For **Title**: Click **+** and select **Title** -* Click **Continue** -* Click **Test Step** (or **Skip Test** to proceed without testing) + +- For **File URL**: Click **+** and select **File** +- For **Title**: Click **+** and select **Title** +- Click **Continue** +- Click **Test Step** (or **Skip Test** to proceed without testing) ![Screenly action configuration](/docs/cookbook/images/zapier-google-drive-04-action-configure.png) @@ -53,11 +57,11 @@ using the toggle switch. ## Step 5 — Test Your Zap -* Upload a file to your selected Google Drive folder -* Wait a few minutes for processing -* Visit [screenly.io](https://www.screenly.io/) and sign in -* Click **Content** in the menu bar -* Verify that your new asset appears +- Upload a file to your selected Google Drive folder +- Wait a few minutes for processing +- Visit [screenly.io](https://www.screenly.io/) and sign in +- Click **Content** in the menu bar +- Verify that your new asset appears You can monitor the Zap's execution in the [Zap history](https://zapier.com/app/history). diff --git a/docs/example-integrations.md b/docs/example-integrations.md index 8ec0f9a..cf8c245 100644 --- a/docs/example-integrations.md +++ b/docs/example-integrations.md @@ -64,4 +64,4 @@ 2. **Content Rotation** - Trigger: Schedule or SharePoint/Dropbox/Box update - Action: Complete Workflow with end dates - - Use Case: Automatically rotate content based on schedules \ No newline at end of file + - Use Case: Automatically rotate content based on schedules diff --git a/index.js b/index.js index 650d7d2..b9acaca 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,8 @@ const authentication = { type: 'string', required: true, label: 'API Key', - helpText: 'See [this page](https://support.screenly.io/hc/en-us/articles/35897560148371-How-to-Generate-a-Screenly-API-Token) for a guide on how to generate an API key for your Screenly account.', + helpText: + 'See [this page](https://support.screenly.io/hc/en-us/articles/35897560148371-How-to-Generate-a-Screenly-API-Token) for a guide on how to generate an API key for your Screenly account.', }, ], }; diff --git a/test/authentication.test.js b/test/authentication.test.js index 22141e9..fd182a0 100644 --- a/test/authentication.test.js +++ b/test/authentication.test.js @@ -40,4 +40,4 @@ describe('Authentication', () => { await expect(appTester(App.authentication.test, bundle)).rejects.toThrow(); }); -}); \ No newline at end of file +}); diff --git a/test/cleanup.test.js b/test/cleanup.test.js index 5614289..d3a12ce 100644 --- a/test/cleanup.test.js +++ b/test/cleanup.test.js @@ -24,10 +24,12 @@ describe('Cleanup', () => { nock('https://api.screenlyapp.com') .get('/api/v4/labels/?name=eq.created_by_zapier') .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(200, [{ - id: 'label-123', - name: 'created_by_zapier' - }]); + .reply(200, [ + { + id: 'label-123', + name: 'created_by_zapier', + }, + ]); // Mock playlist to label mappings nock('https://api.screenlyapp.com') @@ -35,7 +37,7 @@ describe('Cleanup', () => { .matchHeader('Authorization', `Token ${TEST_API_KEY}`) .reply(200, [ { playlist_id: 'playlist-1', label_id: 'label-123' }, - { playlist_id: 'playlist-2', label_id: 'label-123' } + { playlist_id: 'playlist-2', label_id: 'label-123' }, ]); // Mock playlist deletions @@ -87,4 +89,4 @@ describe('Cleanup', () => { appTester(App.creates.cleanup_zapier_content.operation.perform, bundle) ).rejects.toThrow('No labels returned from the Screenly API'); }); -}); \ No newline at end of file +}); diff --git a/test/complete-workflow.test.js b/test/complete-workflow.test.js index 7f5e5c9..15f3cae 100644 --- a/test/complete-workflow.test.js +++ b/test/complete-workflow.test.js @@ -22,28 +22,30 @@ describe('Complete Workflow', () => { }, }; - nock('https://example.com') - .get('/test.jpg') - .reply(200, Buffer.from('fake-image-data')); + nock('https://example.com').get('/test.jpg').reply(200, Buffer.from('fake-image-data')); nock('https://api.screenlyapp.com') .post('/api/v4/assets/', { title: 'Test Asset', source_url: 'https://example.com/test.jpg', - disable_verification: false + disable_verification: false, }) - .reply(201, [{ - id: 'asset-123', - title: 'Test Asset', - }]); + .reply(201, [ + { + id: 'asset-123', + title: 'Test Asset', + }, + ]); nock('https://api.screenlyapp.com') .get('/api/v4/assets?id=eq.asset-123') .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(200, [{ - id: 'asset-123', - status: 'finished', - }]); + .reply(200, [ + { + id: 'asset-123', + status: 'finished', + }, + ]); nock('https://api.screenlyapp.com') .post('/api/v4/playlist-items/', { @@ -58,7 +60,7 @@ describe('Complete Workflow', () => { nock('https://api.screenlyapp.com') .post('/api/v4/labels/playlists', { playlist_id: 'playlist-123', - label_id: 'screen-123' + label_id: 'screen-123', }) .reply(409); // Simulate already assigned @@ -80,26 +82,28 @@ describe('Complete Workflow', () => { }, }; - nock('https://example.com') - .get('/test.jpg') - .reply(200, Buffer.from('fake-image-data')); + nock('https://example.com').get('/test.jpg').reply(200, Buffer.from('fake-image-data')); nock('https://api.screenlyapp.com') .post('/api/v4/assets/') - .reply(201, [{ - id: 'asset-123', - title: 'Test Asset', - }]); + .reply(201, [ + { + id: 'asset-123', + title: 'Test Asset', + }, + ]); nock('https://api.screenlyapp.com') .post('/api/v4/playlists', { title: 'New Playlist', - predicate: new RegExp('TRUE AND \\(\\$DATE >= \\d+\\)') + predicate: new RegExp('TRUE AND \\(\\$DATE >= \\d+\\)'), }) - .reply(201, [{ - id: 'playlist-123', - name: 'New Playlist', - }]); + .reply(201, [ + { + id: 'playlist-123', + name: 'New Playlist', + }, + ]); nock('https://api.screenlyapp.com') .get('/api/v4/labels?name=eq.created_by_zapier') @@ -107,26 +111,28 @@ describe('Complete Workflow', () => { nock('https://api.screenlyapp.com') .post('/api/v4/labels/', { - name: 'created_by_zapier' + name: 'created_by_zapier', }) .reply(201, { - id: 'label-123' + id: 'label-123', }); nock('https://api.screenlyapp.com') .post('/api/v4/labels/playlists', { playlist_id: 'playlist-123', - label_id: 'label-123' + label_id: 'label-123', }) .reply(201); nock('https://api.screenlyapp.com') .get('/api/v4/assets?id=eq.asset-123') .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(200, [{ - id: 'asset-123', - status: 'finished', - }]); + .reply(200, [ + { + id: 'asset-123', + status: 'finished', + }, + ]); nock('https://api.screenlyapp.com') .post('/api/v4/playlist-items/', { @@ -141,7 +147,7 @@ describe('Complete Workflow', () => { nock('https://api.screenlyapp.com') .post('/api/v4/labels/playlists', { playlist_id: 'playlist-123', - label_id: 'screen-123' + label_id: 'screen-123', }) .reply(201); @@ -165,4 +171,4 @@ describe('Complete Workflow', () => { appTester(App.creates.complete_workflow.operation.perform, bundle) ).rejects.toThrow('Either select an existing playlist or provide a name for a new one'); }); -}); \ No newline at end of file +}); diff --git a/test/dynamic-dropdowns.test.js b/test/dynamic-dropdowns.test.js index 91def27..be46f83 100644 --- a/test/dynamic-dropdowns.test.js +++ b/test/dynamic-dropdowns.test.js @@ -72,4 +72,4 @@ describe('Dynamic Dropdowns', () => { expect(response[0].id).toBe('screen-1'); expect(response[1].name).toBe('Screen 2'); }); -}); \ No newline at end of file +}); diff --git a/test/helper-functions.test.js b/test/helper-functions.test.js index 68f798f..39fe07d 100644 --- a/test/helper-functions.test.js +++ b/test/helper-functions.test.js @@ -54,4 +54,4 @@ describe('Helper Functions', () => { }, }); }); -}); \ No newline at end of file +}); diff --git a/test/schedule-playlist-item.test.js b/test/schedule-playlist-item.test.js index 402e359..46ea106 100644 --- a/test/schedule-playlist-item.test.js +++ b/test/schedule-playlist-item.test.js @@ -25,23 +25,27 @@ describe('Schedule Playlist Item', () => { nock('https://api.screenlyapp.com') .get('/api/v4/assets?id=eq.asset-123') .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(200, [{ - id: 'asset-123', - status: 'finished' - }]); + .reply(200, [ + { + id: 'asset-123', + status: 'finished', + }, + ]); nock('https://api.screenlyapp.com') .post('/api/v4/playlist-items/', { asset_id: 'asset-123', playlist_id: 'playlist-123', - duration: 15 + duration: 15, }) .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(201, [{ - id: 'item-123', - playlist_id: 'playlist-123', - asset_id: 'asset-123' - }]); + .reply(201, [ + { + id: 'item-123', + playlist_id: 'playlist-123', + asset_id: 'asset-123', + }, + ]); const response = await appTester(App.creates.schedule_playlist_item.operation.perform, bundle); expect(response.id).toBe('item-123'); @@ -62,23 +66,27 @@ describe('Schedule Playlist Item', () => { nock('https://api.screenlyapp.com') .get('/api/v4/assets?id=eq.asset-123') .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(200, [{ - id: 'asset-123', - status: 'finished' - }]); + .reply(200, [ + { + id: 'asset-123', + status: 'finished', + }, + ]); nock('https://api.screenlyapp.com') .post('/api/v4/playlist-items/', { asset_id: 'asset-123', playlist_id: 'playlist-123', - duration: 20 + duration: 20, }) .matchHeader('Authorization', `Token ${TEST_API_KEY}`) - .reply(201, [{ - id: 'item-123', - playlist_id: 'playlist-123', - asset_id: 'asset-123' - }]); + .reply(201, [ + { + id: 'item-123', + playlist_id: 'playlist-123', + asset_id: 'asset-123', + }, + ]); const response = await appTester(App.creates.schedule_playlist_item.operation.perform, bundle); expect(response.id).toBe('item-123'); @@ -127,4 +135,4 @@ describe('Schedule Playlist Item', () => { appTester(App.creates.schedule_playlist_item.operation.perform, bundle) ).rejects.toThrow(); }); -}); \ No newline at end of file +}); diff --git a/test/upload-asset.test.js b/test/upload-asset.test.js index b071fd3..e8d7ec3 100644 --- a/test/upload-asset.test.js +++ b/test/upload-asset.test.js @@ -31,7 +31,7 @@ describe('Upload Asset', () => { id: 'asset-123', title: 'Test Image', duration: null, - } + }, ]); const response = await appTester(App.creates.upload_asset.operation.perform, bundle); @@ -56,4 +56,4 @@ describe('Upload Asset', () => { await expect(appTester(App.creates.upload_asset.operation.perform, bundle)).rejects.toThrow(); }); -}); \ No newline at end of file +}); diff --git a/test/utils.test.js b/test/utils.test.js index f1b7718..5364925 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -13,7 +13,7 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 200, - json: [{ id: 'label-123', name: 'test-label' }] + json: [{ id: 'label-123', name: 'test-label' }], }), authData: { api_key: TEST_API_KEY }, }; @@ -28,14 +28,15 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 200, - json: [] + json: [], }), authData: { api_key: TEST_API_KEY }, }; const bundle = { authData: { api_key: TEST_API_KEY } }; - await expect(utils.getLabel(z, bundle, { name: 'test-label' })) - .rejects.toThrow('No labels returned from the Screenly API'); + await expect(utils.getLabel(z, bundle, { name: 'test-label' })).rejects.toThrow( + 'No labels returned from the Screenly API' + ); }); }); @@ -44,10 +45,7 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 200, - json: [ - { playlist_id: 'playlist-1' }, - { playlist_id: 'playlist-2' }, - ] + json: [{ playlist_id: 'playlist-1' }, { playlist_id: 'playlist-2' }], }), authData: { api_key: TEST_API_KEY }, }; @@ -62,14 +60,15 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 404, - json: { error: 'Not found' } + json: { error: 'Not found' }, }), authData: { api_key: TEST_API_KEY }, }; const bundle = { authData: { api_key: TEST_API_KEY } }; - await expect(utils.getPlaylistsByLabel(z, bundle, { labelId: 'label-123' })) - .rejects.toThrow('Failed to fetch playlist to labels'); + await expect(utils.getPlaylistsByLabel(z, bundle, { labelId: 'label-123' })).rejects.toThrow( + 'Failed to fetch playlist to labels' + ); }); }); @@ -78,7 +77,7 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 200, - json: {} + json: {}, }), authData: { api_key: TEST_API_KEY }, }; @@ -92,7 +91,7 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 404, - json: { error: 'Not found' } + json: { error: 'Not found' }, }), authData: { api_key: TEST_API_KEY }, }; @@ -108,11 +107,13 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 201, - json: [{ - id: 'playlist-123', - title: 'Test Playlist', - predicate: 'TRUE', - }] + json: [ + { + id: 'playlist-123', + title: 'Test Playlist', + predicate: 'TRUE', + }, + ], }), authData: { api_key: TEST_API_KEY }, }; @@ -130,30 +131,33 @@ describe('Utils', () => { const z = { request: jest.fn().mockResolvedValue({ status: 201, - json: [] + json: [], }), authData: { api_key: TEST_API_KEY }, }; const bundle = { authData: { api_key: TEST_API_KEY } }; - await expect(utils.createPlaylist(z, bundle, { - title: 'Test Playlist', - predicate: 'TRUE', - })).rejects.toThrow('No playlists returned from the Screenly API'); + await expect( + utils.createPlaylist(z, bundle, { + title: 'Test Playlist', + predicate: 'TRUE', + }) + ).rejects.toThrow('No playlists returned from the Screenly API'); }); }); describe('waitForAssetReady', () => { it('waits for asset to be ready', async () => { const z = { - request: jest.fn() + request: jest + .fn() .mockResolvedValueOnce({ status: 200, - json: [{ status: '' }] + json: [{ status: '' }], }) .mockResolvedValueOnce({ status: 200, - json: [{ status: 'finished' }] + json: [{ status: 'finished' }], }), console: { log: jest.fn() }, }; diff --git a/utils.js b/utils.js index f5d2e9b..224ca64 100644 --- a/utils.js +++ b/utils.js @@ -38,7 +38,6 @@ const waitForAssetReady = async (z, assetId, authToken) => { // Log status for debugging z.console.log(`Asset ${assetId} status: ${assetStatus}`); - } while (!READY_STATES.includes(assetStatus)); return assetStatus; @@ -49,14 +48,14 @@ const createAsset = async (z, bundle, { title, sourceUrl, disableVerification = url: 'https://api.screenlyapp.com/api/v4/assets/', method: 'POST', headers: { - 'Authorization': `Token ${bundle.authData.api_key}`, + Authorization: `Token ${bundle.authData.api_key}`, 'Content-Type': 'application/json', - 'Prefer': 'return=representation', + Prefer: 'return=representation', }, body: { title, source_url: sourceUrl, - disable_verification: disableVerification + disable_verification: disableVerification, }, }); @@ -83,9 +82,9 @@ const createPlaylistItem = async (z, bundle, { assetId, playlistId, duration }) url: 'https://api.screenlyapp.com/api/v4/playlist-items/', method: 'POST', headers: { - 'Authorization': `Token ${bundle.authData.api_key}`, + Authorization: `Token ${bundle.authData.api_key}`, 'Content-Type': 'application/json', - 'Prefer': 'return=representation', + Prefer: 'return=representation', }, body: payload, }); @@ -105,8 +104,8 @@ const assignPlaylistToScreen = async (z, bundle, { screenId, playlistId }) => { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, body: { playlist_id: playlistId, @@ -134,8 +133,8 @@ const createPlaylist = async (z, bundle, { title, predicate }) => { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, body: { title, @@ -155,7 +154,7 @@ const createPlaylist = async (z, bundle, { title, predicate }) => { const getLabel = async (z, bundle, { name }) => { const queryParams = { name: `eq.${name}` }; const queryString = Object.keys(queryParams) - .map(key => `${key}=${queryParams[key]}`) + .map((key) => `${key}=${queryParams[key]}`) .join('&'); const response = await z.request({ @@ -163,8 +162,8 @@ const getLabel = async (z, bundle, { name }) => { method: 'GET', headers: { 'Content-Type': 'application/json', - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, }); @@ -181,8 +180,8 @@ const getPlaylistsByLabel = async (z, bundle, { labelId }) => { method: 'GET', headers: { 'Content-Type': 'application/json', - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, }); @@ -195,8 +194,8 @@ const deletePlaylist = async (z, bundle, { playlistId }) => { method: 'DELETE', headers: { 'Content-Type': 'application/json', - 'Authorization': `Token ${bundle.authData.api_key}`, - 'Prefer': 'return=representation', + Authorization: `Token ${bundle.authData.api_key}`, + Prefer: 'return=representation', }, skipThrowForStatus: true, });