diff --git a/__tests__/components/GridItem.test.js b/__tests__/components/GridItem.test.js index df2275fa..ac13bb9a 100755 --- a/__tests__/components/GridItem.test.js +++ b/__tests__/components/GridItem.test.js @@ -1,34 +1,43 @@ import React from 'react'; -import { BrowserRouter } from "react-router-dom"; - -// Testing-specific -import { shallow, mount, render } from 'enzyme'; -const state = require('../state'); - -// Test subjects -import GridItem from '../../src/js/components/GridItem'; +import { shallow } from 'enzyme'; +import { GridItem } from '../../src/js/components/GridItem'; describe('', () => { - it('should handle album', () => { - var album = state.core.albums['jest:album:one']; - var dom = shallow(); - expect(dom.find('.grid__item__name').text()).toEqual('One'); - expect(dom.find('.grid__item__secondary__content').length).toBe(1); - }); + it('should handle album', () => { + const item = { + uri: 'spotify:album:alpha', + name: 'One', + }; + const dom = shallow(); + expect(dom.find('.grid__item__name').text()).toEqual('One'); + expect(dom.find('.grid__item__secondary__content').length).toBe(1); + }); - it('should handle artist', () => { - var artist = state.core.artists['jest:artist:alpha']; - var dom = shallow(); - expect(dom.find('.grid__item__name').text()).toEqual('Alpha'); - expect(dom.find('.grid__item__secondary__content').childAt(0).render().text()).toEqual('123 followers'); - expect(dom.find('.grid__item__secondary__content').childAt(1).render().text()).toEqual('1 albums'); - }); + it('should handle artist', () => { + const item = { + uri: 'spotify:artist:alpha', + name: 'Alpha', + followers: 123, + albums_uris: ['spotify:album:beta'], + }; + const dom = shallow(); + expect(dom.find('.grid__item__name').text()).toEqual('Alpha'); + expect(dom.find('.grid__item__secondary__content').childAt(0).render().text()).toEqual('123 followers'); + expect(dom.find('.grid__item__secondary__content').childAt(1).render().text()).toEqual('1 albums'); + }); - it('should handle playlist', () => { - var playlist = state.core.playlists['jest:playlist:one']; - var dom = shallow(); - expect(dom.find('.grid__item__name').text()).toEqual('One'); - expect(dom.find('.grid__item__secondary__content').render().text()).toEqual('2 tracks'); - }); + it('should handle playlist', () => { + const item = { + uri: 'spotify:playlist:alpha', + name: 'One', + tracks: [ + { uri: 'spotify:track:123' }, + { uri: 'spotify:track:456' }, + ], + }; + const dom = shallow(); + expect(dom.find('.grid__item__name').text()).toEqual('One'); + expect(dom.find('.grid__item__secondary__content').render().text()).toEqual('2 tracks'); + }); }); \ No newline at end of file diff --git a/__tests__/util/helpers.test.js b/__tests__/util/helpers.test.js index e1f414ef..4ae454ce 100755 --- a/__tests__/util/helpers.test.js +++ b/__tests__/util/helpers.test.js @@ -1,236 +1,204 @@ import { - arrays, - storage, - format, - helpers, + arrays, + storage, + format, + helpers, } from '../../src/js/util'; import { isLoading } from '../../src/js/util/helpers'; -const state = require('../state'); - describe('isLoading', () => { - let load_queue = { - 'spotify:playlist:123': 'Some load queue value', - 'stuff:and_things': 'stuff:and_things', - } + const load_queue = { + 'spotify:playlist:123': 'Some load queue value', + 'stuff:and_things': 'stuff:and_things', + }; - it('should return false when not in load_queue', () => { - expect(isLoading(load_queue, ['not_there'])).toBe(false); - }); + it('should return false when not in load_queue', () => { + expect(isLoading(load_queue, ['not_there'])).toBe(false); + }); - it('should return true when in load queue', () => { - expect(isLoading(load_queue, ['stuff:and_things'])).toBe(true); - }); + it('should return true when in load queue', () => { + expect(isLoading(load_queue, ['stuff:and_things'])).toBe(true); + }); - it('should return true when in load queue (regex)', () => { - expect(isLoading(load_queue, ['(.*)playlist(.*)'])).toBe(true); - }); + it('should return true when in load queue (regex)', () => { + expect(isLoading(load_queue, ['(.*)playlist(.*)'])).toBe(true); + }); - it('should return false when regex is invalid', () => { - expect(isLoading(load_queue, ['(*.)playlist(*.)'])).toBe(false); - }); -}); - -// TODO: DELETE THIS, WE USE LOCALFORAGE NOW -describe('localStorage', () => { - - it('should handle keys that are not in storage', () => { - expect(storage.get('invalid_key')).toEqual({}); - expect(storage.get('invalid_key', 'default_value')).toEqual('default_value'); - }); - - it('should store data', () => { - - // Initially empty - expect(storage.get('test_key')).toEqual({}); - - // Set it - storage.set('test_key', 'test_value'); - - // Test storage - expect(storage.get('test_key')).toEqual('test_value'); - }); + it('should return false when regex is invalid', () => { + expect(isLoading(load_queue, ['(*.)playlist(*.)'])).toBe(false); + }); }); describe('isCached', () => { + it('should return false when not cached', () => { + expect(storage.isCached('https://picsum.photos/200')).toBe(false); + }); - it('should return false when not cached', () => { - expect(storage.isCached('https://picsum.photos/200')).toBe(false); - }); - - it('should return true when cached', () => { - var image = new Image(); - image.src = 'https://picsum.photos/200'; - image.onload = function(){ - expect(storage.isCached('https://picsum.photos/200')).toBe(true); - } - }); + it('should return true when cached', () => { + const image = new Image(); + image.src = 'https://picsum.photos/200'; + image.onload = () => { + expect(storage.isCached('https://picsum.photos/200')).toBe(true); + }; + }); }); describe('formatImages', () => { - - it('should ignore already-formatted objects', () => { - var images = [ - { - formatted: true, - small: 'ignored-image.jpg' - } - ]; - expect(format.formatImages(images).small).toBe('ignored-image.jpg'); - }); - - it('should handle Mopidy object', () => { - var images = [ - { - __model__: 'Image', - width: 600, - url: 'test-image.jpg' - } - ]; - expect(format.formatImages(images).small).toBe('test-image.jpg'); - }); - - it('should handle Mopidy string', () => { - var images = ['test-image.jpg']; - expect(format.formatImages(images).small).toBe('test-image.jpg'); - }); - - it('should handle Spotify image', () => { - var images = [ - { - width: 600, - url: 'test-image.jpg' - } - ]; - expect(format.formatImages(images).small).toBe('test-image.jpg'); - }); - - it('should handle LastFM image', () => { - var images = [ - { - size: 'small', - '#text': 'test-image.jpg' - } - ]; - expect(format.formatImages(images).small).toBe('test-image.jpg'); - }); - - it('should handle Genius image', () => { - var images = { - small: { - url: 'test-image.jpg' - } - }; - expect(format.formatImages(images).small).toBe('test-image.jpg'); - }); - - it('should up-fill sizes', () => { - var images = [ - { - width: 50, - url: 'small.jpg' - } - ]; - expect(format.formatImages(images).medium).toBe('small.jpg'); - expect(format.formatImages(images).large).toBe('small.jpg'); - expect(format.formatImages(images).huge).toBe('small.jpg'); - }); - - it('should down-fill sizes', () => { - var images = [ - { - width: 1900, - url: 'huge.jpg' - } - ]; - expect(format.formatImages(images).small).toBe('huge.jpg'); - expect(format.formatImages(images).medium).toBe('huge.jpg'); - expect(format.formatImages(images).large).toBe('huge.jpg'); - }); -}); + it('should ignore already-formatted objects', () => { + let images = [ + { + formatted: true, + small: 'ignored-image.jpg', + }, + ]; + expect(format.formatImages(images).small).toBe('ignored-image.jpg'); + }); + it('should handle Mopidy object', () => { + let images = [ + { + __model__: 'Image', + width: 600, + url: 'test-image.jpg', + }, + ]; + expect(format.formatImages(images).small).toBe('test-image.jpg'); + }); + + it('should handle Mopidy string', () => { + let images = ['test-image.jpg']; + expect(format.formatImages(images).small).toBe('test-image.jpg'); + }); + + it('should handle Spotify image', () => { + let images = [ + { + width: 600, + url: 'test-image.jpg', + }, + ]; + expect(format.formatImages(images).small).toBe('test-image.jpg'); + }); + + it('should handle LastFM image', () => { + let images = [ + { + size: 'small', + '#text': 'test-image.jpg', + }, + ]; + expect(format.formatImages(images).small).toBe('test-image.jpg'); + }); + + it('should handle Genius image', () => { + let images = { + small: { + url: 'test-image.jpg', + }, + }; + expect(format.formatImages(images).small).toBe('test-image.jpg'); + }); + + it('should up-fill sizes', () => { + let images = [ + { + width: 50, + url: 'small.jpg', + }, + ]; + expect(format.formatImages(images).medium).toBe('small.jpg'); + expect(format.formatImages(images).large).toBe('small.jpg'); + expect(format.formatImages(images).huge).toBe('small.jpg'); + }); + + it('should down-fill sizes', () => { + let images = [ + { + width: 1900, + url: 'huge.jpg', + }, + ]; + expect(format.formatImages(images).small).toBe('huge.jpg'); + expect(format.formatImages(images).medium).toBe('huge.jpg'); + expect(format.formatImages(images).large).toBe('huge.jpg'); + }); +}); /** * TODO: Formatters - **/ + * */ - - - - -describe('uriSource', () => { - it('should digest uri into a string', () => { - expect(typeof(helpers.uriType('spotify:album:123'))).toBe('string'); - expect(helpers.uriSource('spotify:album:123')).toBe('spotify'); - }); +describe('uriSource', () => { + it('should digest uri into a string', () => { + expect(typeof (helpers.uriType('spotify:album:123'))).toBe('string'); + expect(helpers.uriSource('spotify:album:123')).toBe('spotify'); + }); }); -describe('uriType', () => { - it('should digest uri into a string', () => { - expect(typeof(helpers.uriType('spotify:album:123'))).toBe('string'); - expect(helpers.uriType('spotify:album:123')).toBe('album'); - }); +describe('uriType', () => { + it('should digest uri into a string', () => { + expect(typeof (helpers.uriType('spotify:album:123'))).toBe('string'); + expect(helpers.uriType('spotify:album:123')).toBe('album'); + }); }); -describe('sourceIcon', () => { - it('should digest uri into a string', () => { - expect(typeof(helpers.sourceIcon('spotify:album:123'))).toBe('string'); - expect(helpers.sourceIcon('spotify:album:123')).toBe('spotify'); - }); +describe('sourceIcon', () => { + it('should digest uri into a string', () => { + expect(typeof (helpers.sourceIcon('spotify:album:123'))).toBe('string'); + expect(helpers.sourceIcon('spotify:album:123')).toBe('spotify'); + }); }); describe('buildLink', () => { + it('should build uri into link as a string', () => { + let link = helpers.buildLink('spotify:album:123'); + expect(typeof (link)).toBe('string'); + expect(link).toBe('/album/spotify%3Aalbum%3A123'); + }); - it('should build uri into link as a string', () => { - var link = helpers.buildLink('spotify:album:123'); - expect(typeof(link)).toBe('string'); - expect(link).toBe('/album/spotify%3Aalbum%3A123'); - }); - - it('should handle special characters', () => { - var link = helpers.buildLink('spotify:album:http://test.com/123!@#$%^&[];<>/?" .mp3'); - expect(typeof(link)).toBe('string'); - expect(link).toBe('/album/spotify%3Aalbum%3Ahttp%3A%2F%2Ftest.com%2F123!%40%23%24%25%5E%26%5B%5D%3B%3C%3E%2F%3F%22%20.mp3'); - }); + it('should handle special characters', () => { + let link = helpers.buildLink('spotify:album:http://test.com/123!@#$%^&[];<>/?" .mp3'); + expect(typeof (link)).toBe('string'); + expect(link).toBe('/album/spotify%3Aalbum%3Ahttp%3A%2F%2Ftest.com%2F123!%40%23%24%25%5E%26%5B%5D%3B%3C%3E%2F%3F%22%20.mp3'); + }); }); describe('arrayOf', () => { + it('should return a one-dimensional array', () => { + const items = [ + { + uri: '123', + name: '123', + }, + { + uri: '456', + name: '456', + }, + ]; + const uris = arrays.arrayOf('uri', items); + expect(Array.isArray(uris)).toBe(true); + expect(uris.length).toBe(2); - it('should return a one-dimensional array', () => { - var items = [ - { - uri: '123', - name: '123' - }, - { - uri: '456', - name: '456' - } - ]; - var uris = arrays.arrayOf('uri', items); - expect(Array.isArray(uris)).toBe(true); - expect(uris.length).toBe(2); + for (let uri of uris) { + expect(typeof (uri)).toBe('string'); + } + }); - for (var uri of uris){ - expect(typeof(uri)).toBe('string'); - } - }); - - it('should remove null and undefined items', () => { - var items = [ - { - uri: '123', - name: '123' - }, - { - uri: null, - name: '456' - }, - { - name: '789' - } - ]; - var uris = arrays.arrayOf('uri', items); - expect(uris.length).toBe(1); - }); -}); \ No newline at end of file + it('should remove null and undefined items', () => { + let items = [ + { + uri: '123', + name: '123', + }, + { + uri: null, + name: '456', + }, + { + name: '789', + }, + ]; + let uris = arrays.arrayOf('uri', items); + expect(uris.length).toBe(1); + }); +}); diff --git a/__tests__/views/Album.test.js b/__tests__/views/Album.test.js index bec4f508..2ce3beaf 100755 --- a/__tests__/views/Album.test.js +++ b/__tests__/views/Album.test.js @@ -1,33 +1,39 @@ import React from 'react'; +import { shallow } from 'enzyme'; -// Testing-specific -import { shallow, mount, render } from 'enzyme'; -const state = require('../state'); - -// Test subjects import { Album } from '../../src/js/views/Album'; import * as uiActions from '../../src/js/services/ui/actions'; import * as coreActions from '../../src/js/services/core/actions'; +const state = require('../state'); describe('', () => { + const album = { + uri: 'jest:album:one', + name: 'One', + artists_uris: [ + 'jest:artist:alpha', + ], + tracks_uris: [ + 'jest:track:one', + 'jest:track:two', + ], + wiki: 'Wiki text', + }; - var album = state.core.albums['jest:album:one']; - - it('should render accurately', () => { - const dom = shallow( - { + const dom = shallow( + , { - disableLifecycleMethods: true, + disableLifecycleMethods: true, }, - ); + ); - expect(dom.find('.album-view').length).toBe(1); - - expect(dom.find('h1').text()).toEqual('One'); - expect(dom.find('.wiki__text p').text()).toEqual('Wiki text'); - }); -}); \ No newline at end of file + expect(dom.find('.album-view').length).toBe(1); + expect(dom.find('h1').text()).toEqual('One'); + expect(dom.find('.wiki__text p').text()).toEqual('Wiki text'); + }); +}); diff --git a/src/js/components/GridItem.js b/src/js/components/GridItem.js index d6ad865a..1c4a832d 100755 --- a/src/js/components/GridItem.js +++ b/src/js/components/GridItem.js @@ -55,7 +55,8 @@ class GridItem extends React.Component { renderSecondary = ({ uri, - tracks_total, + tracks_total = 0, + tracks, followers, albums_uris, artists, @@ -64,7 +65,7 @@ class GridItem extends React.Component { case 'playlist': return ( - + ); @@ -95,7 +96,9 @@ class GridItem extends React.Component { render = () => { const { - item: { album }, + item: { + album, + } = {}, link: customLink, type, show_source_icon, @@ -149,4 +152,8 @@ const mapStateToProps = (state) => { }; }; +export { + GridItem, +}; + export default connect(mapStateToProps)(GridItem); diff --git a/src/js/util/arrays.js b/src/js/util/arrays.js index 276e9b7c..75bc5607 100755 --- a/src/js/util/arrays.js +++ b/src/js/util/arrays.js @@ -26,7 +26,13 @@ const indexToArray = (index, keys) => { * */ const arrayOf = (property, items = []) => { const array = []; - items.forEach((item) => (item[property] !== undefined ? array.push(item[property]) : null)); + items.forEach( + (item) => { + if (item[property] === undefined) return; + if (item[property] === null) return; + array.push(item[property]); + }, + ); return array; }; diff --git a/src/js/util/helpers.js b/src/js/util/helpers.js index 75266e8a..8d8ef770 100755 --- a/src/js/util/helpers.js +++ b/src/js/util/helpers.js @@ -375,13 +375,14 @@ let isObject = function (value) { const isLoading = function (load_queue = {}, keys = []) { if (!load_queue || !keys) return false; - const queue_keys = indexToArray(load_queue); + const queue_keys = Object.keys(load_queue); const matches = keys.reduce((acc, key) => { let regex = ''; try { regex = new RegExp(key); } catch { - console.error('Invalid regular expression', keys); + // Fucks with unit tests, but helpful for debugging. + // console.error('Invalid regular expression', keys); return acc; } diff --git a/src/js/views/Album.js b/src/js/views/Album.js index 2d583895..4bdb14ab 100755 --- a/src/js/views/Album.js +++ b/src/js/views/Album.js @@ -21,14 +21,12 @@ import * as spotifyActions from '../services/spotify/actions'; import * as lastfmActions from '../services/lastfm/actions'; import { uriSource, - getFromUri, - isLoading, sourceIcon, } from '../util/helpers'; import Button from '../components/Button'; -import { makeLoadingSelector, makeItemSelector, makeLibrarySelector } from '../util/selectors'; +import { makeLoadingSelector, makeItemSelector } from '../util/selectors'; -export class Album extends React.Component { +class Album extends React.Component { componentDidMount = () => { const { uri, @@ -305,6 +303,10 @@ const mapDispatchToProps = (dispatch) => ({ lastfmActions: bindActionCreators(lastfmActions, dispatch), }); +export { + Album, +}; + export default connect( mapStateToProps, mapDispatchToProps,