Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
miagilepner committed Jul 8, 2021
1 parent d09614e commit 2b221cb
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 30 deletions.
13 changes: 8 additions & 5 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
UserFilters,
UserResponse,
UserSort,
SearchMessageSort,
} from './types';
import { Role } from './permissions';

Expand Down Expand Up @@ -317,7 +318,7 @@ export class Channel<
UserType
>
| string,
options: SearchOptions & {
options: SearchOptions<MessageType> & {
client_id?: string;
connection_id?: string;
message_filter_conditions?: MessageFilters<
Expand All @@ -331,8 +332,11 @@ export class Channel<
query?: string;
} = {},
) {
if ('offset' in options && ('sort' in options || 'next' in options)) {
throw Error(`Cannot specify offset with sort or next parameters`);
}
// Return a list of channels
const { sort, ...optionsWithoutSort } = { ...options };
const { sort: sortValue, ...optionsWithoutSort } = { ...options };
const payload: SearchPayload<
AttachmentType,
ChannelType,
Expand All @@ -355,9 +359,8 @@ export class Channel<
} else {
throw Error(`Invalid type ${typeof query} for query parameter`);
}

if (sort) {
payload.sort = normalizeQuerySort(sort);
if (sortValue) {
payload.sort = normalizeQuerySort<SearchMessageSort<MessageType>>(sortValue);
}
// Make sure we wait for the connect promise if there is a pending one
await this.getClient().wsPromise;
Expand Down
16 changes: 10 additions & 6 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import {
UserOptions,
UserResponse,
UserSort,
SearchMessageSort,
} from './types';

function isString(x: unknown): x is string {
Expand Down Expand Up @@ -1761,7 +1762,7 @@ export class StreamChat<
*
* @param {ChannelFilters<ChannelType, CommandType, UserType>} filterConditions MongoDB style filter conditions
* @param {MessageFilters<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType> | string} query search query or object MongoDB style filters
* @param {SearchOptions} [options] Option object, {user_id: 'tommaso'}
* @param {SearchOptions<MessageType>} [options] Option object, {user_id: 'tommaso'}
*
* @return {Promise<SearchAPIResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>>} search messages response
*/
Expand All @@ -1777,9 +1778,12 @@ export class StreamChat<
ReactionType,
UserType
>,
options: SearchOptions = {},
options: SearchOptions<MessageType> = {},
) {
const { sort: sort_value, ...options_without_sort } = { ...options };
if ('offset' in options && ('sort' in options || 'next' in options)) {
throw Error(`Cannot specify offset with sort or next parameters`);
}
const { sort: sortValue, ...optionsWithoutSort } = { ...options };
const payload: SearchPayload<
AttachmentType,
ChannelType,
Expand All @@ -1789,7 +1793,7 @@ export class StreamChat<
UserType
> = {
filter_conditions: filterConditions,
...options_without_sort,
...optionsWithoutSort,
};
if (typeof query === 'string') {
payload.query = query;
Expand All @@ -1798,8 +1802,8 @@ export class StreamChat<
} else {
throw Error(`Invalid type ${typeof query} for query parameter`);
}
if (sort_value) {
payload.sort = normalizeQuerySort(sort_value);
if (sortValue) {
payload.sort = normalizeQuerySort<SearchMessageSort<MessageType>>(sortValue);
}

// Make sure we wait for the connect promise if there is a pending one
Expand Down
37 changes: 20 additions & 17 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -944,19 +944,13 @@ export type QueryMembersOptions = {
user_id_lte?: string;
};

export type LimitOffsetSearchOptions = {
limit?: number;
offset?: number;
};

export type NextSearchOptions = {
export type SearchOptions<MessageType = UnknownType> = {
limit?: number;
next?: string;
sort?: SearchMessageSort;
offset?: number;
sort?: SearchMessageSort<MessageType>;
};

export type SearchOptions = LimitOffsetSearchOptions | NextSearchOptions;

export type StreamChatOptions = AxiosRequestConfig & {
/**
* Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.
Expand Down Expand Up @@ -1424,12 +1418,21 @@ export type UserSort<UserType = UnknownType> =
| Sort<UserResponse<UserType>>
| Array<Sort<UserResponse<UserType>>>;

export type SearchRelevanceSort = { relevance?: AscDesc };

export type SearchMessageSortBase<MessageType = UnknownType> =
| SearchRelevanceSort
| Sort<MessageType>
| { [field: string]: AscDesc };
export type SearchMessageSortBase<MessageType = UnknownType> = Sort<MessageType> & {
attachments?: AscDesc;
'attachments.type'?: AscDesc;
created_at?: AscDesc;
id?: AscDesc;
'mentioned_users.id'?: AscDesc;
parent_id?: AscDesc;
pinned?: AscDesc;
relevance?: AscDesc;
reply_count?: AscDesc;
text?: AscDesc;
type?: AscDesc;
updated_at?: AscDesc;
'user.id'?: AscDesc;
};

export type SearchMessageSort<MessageType = UnknownType> =
| SearchMessageSortBase<MessageType>
Expand Down Expand Up @@ -1931,7 +1934,7 @@ export type SearchPayload<
MessageType = UnknownType,
ReactionType = UnknownType,
UserType = UnknownType
> = Omit<SearchOptions, 'sort'> & {
> = Omit<SearchOptions<MessageType>, 'sort'> & {
client_id?: string;
connection_id?: string;
filter_conditions?: ChannelFilters<ChannelType, CommandType, UserType>;
Expand All @@ -1946,7 +1949,7 @@ export type SearchPayload<
query?: string;
sort?: Array<{
direction: AscDesc;
field: string | number;
field: Extract<keyof SearchMessageSortBase<MessageType>, string>;
}>;
};

Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function normalizeQuerySort<T extends QuerySort>(sort: T) {
const sortArr = Array.isArray(sort) ? sort : [sort];
for (const item of sortArr) {
const entries = (Object.entries(item) as unknown) as [
T extends (infer K)[] ? keyof K : keyof T,
T extends (infer K)[] ? Extract<keyof K, string> : Extract<keyof T, string>,
AscDesc,
][];
if (entries.length > 1) {
Expand Down
31 changes: 31 additions & 0 deletions test/unit/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,34 @@ describe('event subscription and unsubscription', () => {
expect(channel.listeners['all'].length).to.be.equal(0);
});
});
describe('Channel search', async () => {
const client = await getClientWithUser();
const channel = client.channel('messaging', uuidv4());

it('search with sorting by defined field', async () => {
client.get = (url, config) => {
expect(config.payload.sort).to.be.eql([
{ field: 'updated_at', direction: -1 },
]);
};
await channel.search('query', { sort: [{ updated_at: -1 }] });
});
it('search with sorting by custom field', async () => {
client.get = (url, config) => {
expect(config.payload.sort).to.be.eql([
{ field: 'custom_field', direction: -1 },
]);
};
await channel.search('query', { sort: [{ custom_field: -1 }] });
});
it('sorting and offset fails', async () => {
await expect(
channel.search('query', { offset: 1, sort: [{ custom_field: -1 }] }),
).to.be.rejectedWith(Error);
});
it('next and offset fails', async () => {
await expect(
channel.search('query', { offset: 1, next: 'next' }),
).to.be.rejectedWith(Error);
});
});
44 changes: 43 additions & 1 deletion test/unit/client.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import chai from 'chai';

import chaiAsPromised from 'chai-as-promised';
import { generateMsg } from './test-utils/generateMessage';
import { getClientWithUser } from './test-utils/getClient';

import { StreamChat } from '../../src/client';

const expect = chai.expect;
chai.use(chaiAsPromised);

describe('StreamChat getInstance', () => {
beforeEach(() => {
Expand Down Expand Up @@ -268,3 +269,44 @@ describe('updateMessage should ensure sanity of `mentioned_users`', () => {
);
});
});

describe('Client search', async () => {
const client = await getClientWithUser();

it('search with sorting by defined field', async () => {
client.get = (url, config) => {
expect(config.payload.sort).to.be.eql([
{ field: 'updated_at', direction: -1 },
]);
};
await client.search({ cid: 'messaging:my-cid' }, 'query', {
sort: [{ updated_at: -1 }],
});
});
it('search with sorting by custom field', async () => {
client.get = (url, config) => {
expect(config.payload.sort).to.be.eql([
{ field: 'custom_field', direction: -1 },
]);
};
await client.search({ cid: 'messaging:my-cid' }, 'query', {
sort: [{ custom_field: -1 }],
});
});
it('sorting and offset fails', async () => {
await expect(
client.search({ cid: 'messaging:my-cid' }, 'query', {
offset: 1,
sort: [{ custom_field: -1 }],
}),
).to.be.rejectedWith(Error);
});
it('next and offset fails', async () => {
await expect(
client.search({ cid: 'messaging:my-cid' }, 'query', {
offset: 1,
next: 'next',
}),
).to.be.rejectedWith(Error);
});
});

0 comments on commit 2b221cb

Please sign in to comment.