Skip to content

Commit

Permalink
Fix: Exclude questionmark from URL when not sending request params (#140
Browse files Browse the repository at this point in the history
)

* split tests between unit and integration

* rename test files to include '.test.'

* use mocks in tests

* use separate tsconfig for tests

* add (failing) tests to assert desired behavior

* fix implementation

* prettier-ignore the output files
  • Loading branch information
lionralfs committed Apr 2, 2023
1 parent f24b539 commit 158c468
Show file tree
Hide file tree
Showing 31 changed files with 423 additions and 173 deletions.
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
commonjs/**/*.js
coverage/
coverage/
browser/index.js
node-esm/index.js
2 changes: 1 addition & 1 deletion lib/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export default function (client: DiscogsClient) {
SortParameters<'label' | 'artist' | 'title' | 'catno' | 'format' | 'rating' | 'added' | 'year'>
): Promise<RateLimitedResponse<GetReleasesResponse & PaginationResponse>> {
if (client.authenticated(2) || Number(folder) === 0) {
const path = `/users/${escape(user)}/collection/folders/${folder}/releases?${toQueryString(params)}`;
const path = `/users/${escape(user)}/collection/folders/${folder}/releases${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<GetReleasesResponse & PaginationResponse>>;
}
return Promise.reject(new AuthError());
Expand Down
19 changes: 7 additions & 12 deletions lib/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export default function (client: DiscogsClient) {
artist: number | string,
params?: PaginationParameters & SortParameters<'year' | 'title' | 'format'>
): Promise<RateLimitedResponse<GetArtistReleasesResponses & PaginationResponse>> {
const path = `/artists/${artist}/releases?${toQueryString(params)}`;
const path = `/artists/${artist}/releases${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<GetArtistReleasesResponses & PaginationResponse>>;
},

Expand All @@ -234,7 +234,7 @@ export default function (client: DiscogsClient) {
): Promise<RateLimitedResponse<GetReleaseResponse>> {
let path = `/releases/${release}`;
if (currency !== undefined) {
path += `?${toQueryString({ curr_abbr: currency })}`;
path += `${toQueryString({ curr_abbr: currency })}`;
}
return client.get(path) as Promise<RateLimitedResponse<GetReleaseResponse>>;
},
Expand Down Expand Up @@ -366,7 +366,7 @@ export default function (client: DiscogsClient) {
>
>
): Promise<RateLimitedResponse<GetMasterVersionsResponse & PaginationResponse>> {
const path = `/masters/${master}/versions?${toQueryString(params)}`;
const path = `/masters/${master}/versions${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<GetMasterVersionsResponse & PaginationResponse>>;
},

Expand Down Expand Up @@ -399,7 +399,7 @@ export default function (client: DiscogsClient) {
label: number | string,
params?: PaginationParameters
): Promise<RateLimitedResponse<GetLabelReleasesResponse & PaginationResponse>> {
const path = `/labels/${label}/releases?${toQueryString(params)}`;
const path = `/labels/${label}/releases${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<GetLabelReleasesResponse & PaginationResponse>>;
},

Expand Down Expand Up @@ -436,14 +436,9 @@ export default function (client: DiscogsClient) {
search: function (
params: PaginationParameters & Partial<SearchParameters> = {}
): Promise<RateLimitedResponse<SearchResponse & PaginationResponse>> {
const args = { ...params };
if (args.query) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
args.q = args.query;
delete args.query;
}
return client.get({ url: `/database/search?${toQueryString(args)}`, authLevel: 1 }) as Promise<
const { query, ...inputArgs } = params;
const args = query ? Object.assign(inputArgs, { q: query }) : inputArgs;
return client.get({ url: `/database/search${toQueryString(args)}`, authLevel: 1 }) as Promise<
RateLimitedResponse<SearchResponse & PaginationResponse>
>;
},
Expand Down
10 changes: 5 additions & 5 deletions lib/marketplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export default function (client: DiscogsClient) {
getListing: function (listing: number, currency?: Currency): Promise<RateLimitedResponse<Listing>> {
let path = `/marketplace/listings/${listing}`;
if (currency !== undefined) {
path += `?${toQueryString({ curr_abbr: currency })}`;
path += `${toQueryString({ curr_abbr: currency })}`;
}
return client.get(path) as Promise<RateLimitedResponse<Listing>>;
},
Expand Down Expand Up @@ -229,7 +229,7 @@ export default function (client: DiscogsClient) {
PaginationParameters &
SortParameters<'id' | 'buyer' | 'created' | 'status' | 'last_activity'>
): Promise<RateLimitedResponse<PaginationResponse & { orders: Array<GetOrderResponse> }>> {
const path = `/marketplace/orders?${toQueryString(params)}`;
const path = `/marketplace/orders${toQueryString(params)}`;
return client.get({ url: path, authLevel: 2 }) as Promise<
RateLimitedResponse<PaginationResponse & { orders: Array<GetOrderResponse> }>
>;
Expand Down Expand Up @@ -286,7 +286,7 @@ export default function (client: DiscogsClient) {
order: number,
params?: PaginationParameters
): Promise<RateLimitedResponse<PaginationResponse & { messages: Array<OrderMessage> }>> {
const path = `/marketplace/orders/${order}/messages?${toQueryString(params)}`;
const path = `/marketplace/orders/${order}/messages${toQueryString(params)}`;
return client.get({ url: path, authLevel: 2 }) as Promise<
RateLimitedResponse<PaginationResponse & { messages: Array<OrderMessage> }>
>;
Expand Down Expand Up @@ -370,9 +370,9 @@ export default function (client: DiscogsClient) {
): Promise<RateLimitedResponse<GetReleaseStatsResponse>> {
let path = `/marketplace/stats/${release}`;
if (currency) {
path += `?${toQueryString({ curr_abbr: currency })}`;
path += `${toQueryString({ curr_abbr: currency })}`;
}
return client.get({ url: path }) as Promise<RateLimitedResponse<GetReleaseStatsResponse>>;
return client.get(path) as Promise<RateLimitedResponse<GetReleaseStatsResponse>>;
},
};
}
8 changes: 4 additions & 4 deletions lib/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default function (client: DiscogsClient) {
'listed' | 'price' | 'item' | 'artist' | 'label' | 'catno' | 'audio' | 'status' | 'location'
>
): Promise<RateLimitedResponse<GetInventoryResponse & PaginationResponse>> {
const path = `/users/${escape(user)}/inventory?${toQueryString(params)}`;
const path = `/users/${escape(user)}/inventory${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<GetInventoryResponse & PaginationResponse>>;
},

Expand Down Expand Up @@ -198,7 +198,7 @@ export default function (client: DiscogsClient) {
params?: PaginationParameters &
SortParameters<'label' | 'artist' | 'title' | 'catno' | 'format' | 'rating' | 'year' | 'added'>
): Promise<RateLimitedResponse<GetContributionsResponse & PaginationResponse>> {
const path = `/users/${escape(user)}/contributions?${toQueryString(params)}`;
const path = `/users/${escape(user)}/contributions${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<GetContributionsResponse & PaginationResponse>>;
},

Expand All @@ -217,7 +217,7 @@ export default function (client: DiscogsClient) {
user: string,
params?: PaginationParameters
): Promise<RateLimitedResponse<PaginationResponse & GetSubmissionsResponse>> {
const path = `/users/${escape(user)}/submissions?${toQueryString(params)}`;
const path = `/users/${escape(user)}/submissions${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<PaginationResponse & GetSubmissionsResponse>>;
},

Expand All @@ -236,7 +236,7 @@ export default function (client: DiscogsClient) {
user: string,
params?: PaginationParameters
): Promise<RateLimitedResponse<PaginationResponse & GetListsResponse>> {
const path = `/users/${escape(user)}/lists?${toQueryString(params)}`;
const path = `/users/${escape(user)}/lists${toQueryString(params)}`;
return client.get(path) as Promise<RateLimitedResponse<PaginationResponse & GetListsResponse>>;
},
};
Expand Down
6 changes: 3 additions & 3 deletions lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ export function stripVariation(name: string): string {
}

/**
* Turns a simple key-value object into a query string
* Turns a simple key-value object into a query string (including the leading questionmark)
* @param {Record<string, string | number>} data - Data object containing the params
* @returns {string}
*/
export function toQueryString(data?: Record<PropertyKey, string | number | boolean>): string {
if (!data) {
if (!data || !Object.keys(data).length) {
return '';
}

const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(data)) {
searchParams.set(key, value.toString());
}
return searchParams.toString();
return '?' + searchParams.toString();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions lib/wantlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ export default function (client: DiscogsClient) {
*/
getReleases: function (
user: string,
params: PaginationParameters
params?: PaginationParameters
): Promise<RateLimitedResponse<PaginationResponse & { wants: Array<WantlistEntryResponse> }>> {
const path = `/users/${escape(user)}/wants?${toQueryString(params)}`;
const path = `/users/${escape(user)}/wants${toQueryString(params)}`;

return client.get(path) as Promise<
RateLimitedResponse<PaginationResponse & { wants: Array<WantlistEntryResponse> }>
Expand Down
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
},
"devDependencies": {
"@esbuild-kit/esm-loader": "^2.5.0",
"@fluffy-spoon/substitute": "^1.208.0",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"ava": "^5.0.1",
Expand Down
41 changes: 0 additions & 41 deletions test/error.ts

This file was deleted.

File renamed without changes.
68 changes: 2 additions & 66 deletions test/client.ts → test/integration/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,10 @@
import test from 'ava';
import { rest } from 'msw';
import { DiscogsClient } from '../lib/client.js';
import { setupMockAPI } from './_setup.js';
import { DiscogsClient } from '@lib/client.js';
import { setupMockAPI } from './_setup.test.js';

const server = setupMockAPI();

test('DiscogsClient: Test instance', t => {
t.true(new DiscogsClient() instanceof DiscogsClient);
});

test('DiscogsClient: Test authenticated()', t => {
t.false(new DiscogsClient().authenticated(1), 'Authentication level 1 === false');
});

test('DiscogsClient: Test setConfig with exponential backoff parameters', t => {
// Given
const client = new DiscogsClient();

// When
client.setConfig({
exponentialBackoffMaxRetries: 333,
exponentialBackoffIntervalMs: 444,
exponentialBackoffRate: 555,
});

// Then

t.is(client['config'].exponentialBackoffMaxRetries, 333);
t.is(client['config'].exponentialBackoffIntervalMs, 444);
t.is(client['config'].exponentialBackoffRate, 555);
});

test.serial('DiscogsClient: Test get()', async t => {
t.plan(1);
server.use(
Expand Down Expand Up @@ -127,44 +101,6 @@ test.serial('DiscogsClient: Auth (userToken)', async t => {
await client.getIdentity();
});

test('DiscogsClient: Auth (Full OAuth)', t => {
const client = new DiscogsClient({
auth: {
method: 'oauth',
consumerKey: 'consumerKey',
consumerSecret: 'consumerSecret',
accessToken: 'accessToken',
accessTokenSecret: 'accessTokenSecret',
},
});

t.deepEqual(client['auth'], {
method: 'oauth',
level: 2,
consumerKey: 'consumerKey',
consumerSecret: 'consumerSecret',
accessToken: 'accessToken',
accessTokenSecret: 'accessTokenSecret',
});
});

test('DiscogsClient: Auth (OAuth without tokens)', t => {
const client = new DiscogsClient({
auth: {
method: 'oauth',
consumerKey: 'consumerKey',
consumerSecret: 'consumerSecret',
},
});

t.deepEqual(client['auth'], {
method: 'oauth',
level: 1,
consumerKey: 'consumerKey',
consumerSecret: 'consumerSecret',
});
});

test.serial('DiscogsClient: Sends OAuth header', async t => {
t.plan(1);

Expand Down
17 changes: 2 additions & 15 deletions test/collection.ts → test/integration/collection.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava';
import { rest } from 'msw';
import { DiscogsClient } from '../lib/client.js';
import { setupMockAPI } from './_setup.js';
import { DiscogsClient } from '@lib/client.js';
import { setupMockAPI } from './_setup.test.js';

const server = setupMockAPI();

Expand Down Expand Up @@ -53,11 +53,6 @@ test.serial('Collection: Get folder metadata (no auth required for public folder
await client.user().collection().getFolder('rodneyfool', 0);
});

test('Collection: Get folder metadata (throws auth error)', async t => {
const client = new DiscogsClient();
await t.throwsAsync(client.user().collection().getFolder('rodneyfool', 1234));
});

test.serial('Collection: Edit folder name', async t => {
t.plan(1);
server.use(
Expand Down Expand Up @@ -130,14 +125,6 @@ test.serial('Collection: Collection items by folder (default doesnt need auth)',
await client.user().collection().getReleases('rodneyfool', '0', { sort: 'artist', sort_order: 'desc' });
});

test('Collection: Collection items by folder (throws auth error)', async t => {
t.plan(1);
const client = new DiscogsClient();
await t.throwsAsync(
client.user().collection().getReleases('rodneyfool', '1234', { sort: 'artist', sort_order: 'desc' })
);
});

test.serial('Collection: Add release to folder', async t => {
t.plan(1);
server.use(
Expand Down
Loading

0 comments on commit 158c468

Please sign in to comment.