Skip to content

Commit

Permalink
Update search tests and lintings (#40)
Browse files Browse the repository at this point in the history
* fix linting

* include descriptions; and flatten resolved data

* cover new api endpoints
  • Loading branch information
vutran authored Oct 21, 2016
1 parent 8141084 commit 524769c
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 22 deletions.
40 changes: 40 additions & 0 deletions __tests__/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ERR_MODULE_NOT_FOUND,
ERR_MODULE_DISABLED,
ERR_MODULE_REMOVE_FAILED,
ERR_MODULE_SEARCH_FAILED,
ERR_THEME_ALREADY_ACTIVE,
} from '../../src/errors';

Expand Down Expand Up @@ -152,3 +153,42 @@ describe('themes', () => {
}
});
});

describe('search', () => {
it('should return some search results', async () => {
const mockHttpResponse = {
results: [
{
name: ['foobar-default-theme'],
description: ['Foobar default theme'],
},
{
name: ['foobar-default-plugin'],
description: ['Foobar default plugin'],
},
],
};
require('http').__setMockResponse(JSON.stringify(mockHttpResponse));
expect(await api.search('foobar')).toContainEqual({
name: 'foobar-default-theme',
desc: 'Foobar default theme',
});

expect(await api.search('foobar')).not.toContainEqual({
name: 'invalid-default-theme',
desc: 'Invalid default theme',
});
});

it('should fail to receive search results', async () => {
const mockHttpResponse = {
results: null,
};
require('http').__setMockResponse(JSON.stringify(mockHttpResponse));
try {
await api.search('foobar');
} catch (err) {
expect(err).toBe(ERR_MODULE_SEARCH_FAILED);
}
});
});
30 changes: 25 additions & 5 deletions __tests__/utils/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,36 @@ jest.mock('http');

describe('search', () => {
it('should seach for packages', async () => {
const mockHttpResponse = {results: [{"name":["foobar-default-theme"]},{"name":["foobar-default-plugin"]}]};
const mockHttpResponse = {
results: [
{
name: ['foobar-default-theme'],
description: ['Foobar default theme'],
},
{
name: ['foobar-default-plugin'],
description: ['Foobar default plugin'],
},
],
};
require('http').__setMockResponse(JSON.stringify(mockHttpResponse));

const pkg = 'foobar';
const mockResponse = [{"name":["foobar-default-theme"]},{"name":["foobar-default-plugin"]}];
expect(await search.searchPackages(pkg)).toEqual(mockResponse);
const q = 'foobar';
const mockResponse = [
{
name: 'foobar-default-theme',
desc: 'Foobar default theme',
},
{
name: 'foobar-default-plugin',
desc: 'Foobar default plugin',
},
];
expect(await search.searchPackages(q)).toEqual(mockResponse);
});

it('should retrieve the package url', () => {
const pkg = 'foobar';
expect(search.getSearchUrl(pkg)).toEqual('http://npmsearch.com/query\?q\=foobar%20AND%20\(keywords:dext-theme%20OR%20keywords:dext-plugin\)\&fields\=name');
expect(search.getSearchUrl(pkg)).toEqual('https://npmsearch.com/query?q=foobar%20AND%20(keywords:dext-theme%20OR%20keywords:dext-plugin)&fields=name,description');
});
});
15 changes: 7 additions & 8 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,16 @@ const config = new Conf();
* Lists plugins & themes with the keyword 'dext-plugin' or 'dext-theme' on npm
*
* @param {String} plugin - The name of the plugin/theme
* @return {Promise} - Resolves the search results as an array
* @return {Promise} - Resolves the search results
*/
const search = (searchTerm) => new Promise((resolve, reject) => {
searchPackages(searchTerm).then(packages => {
if(Array.isArray(packages)) {
// Loop over all found packages to return a list
const results = packages.map(pkg => pkg.name[0]);
resolve(results);
} else {
const search = searchTerm => new Promise((resolve, reject) => {
searchPackages(searchTerm).then((packages) => {
if (!Array.isArray(packages) || !packages.length) {
reject(ERR_MODULE_SEARCH_FAILED);
return;
}

resolve(packages);
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ module.exports = {
conf,
download,
paths,
search
search,
};
33 changes: 25 additions & 8 deletions src/utils/search.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
const http = require('http');

const getSearchUrl = pkg => `http://npmsearch.com/query\?q\=${pkg}%20AND%20\(keywords:dext-theme%20OR%20keywords:dext-plugin\)\&fields\=name`;
/**
* Retrieves the API url
*
* @param {String} q - The keyword to search
* @return {String}
*/
const getSearchUrl = q => `https://npmsearch.com/query?q=${q}%20AND%20(keywords:dext-theme%20OR%20keywords:dext-plugin)&fields=name,description`;

/**
* Searches for package marked with the keywords 'dext-plugin' or 'dext-theme'
* Searches for packages marked with the keywords 'dext-plugin' or 'dext-theme'
*
* { name, desc }
*
* @param {String} pkg - The name of the npm package
* @return {Promise} - The search results
* @param {String} q - A keyword to search for (queried by package name)
* @return {Promise} - Resolves an array of the package names and descriptions
*/
const searchPackages = (pkg) => new Promise((resolve) => {
const searchPackages = q => new Promise((resolve) => {
let body = '';
const endpoint = getSearchUrl(q);
// Retrieve the search results
return http.get(getSearchUrl(pkg), (res) => {
return http.get(endpoint, (res) => {
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
const results = JSON.parse(body);
if (!results.results) {
resolve([]);
return;
}
const resultsFlat = results.results.map(c => ({
name: c.name[0],
desc: c.description ? c.description[0] : '',
}));
// Return the results part of the HTTP response
resolve(results.results);
resolve(resultsFlat);
});
});
});

module.exports = {
getSearchUrl,
searchPackages
searchPackages,
};

0 comments on commit 524769c

Please sign in to comment.