Add ListSenderNames api route and use params.Add(..) in Filter classes
This commit is contained in:
parent
352f1ca0d1
commit
d21d775764
@ -29,12 +29,13 @@ enum ChannelSelector {
|
|||||||
|
|
||||||
class MessageFilter {
|
class MessageFilter {
|
||||||
List<String>? channelIDs;
|
List<String>? channelIDs;
|
||||||
String? searchFilter;
|
List<String>? searchFilter;
|
||||||
List<String>? senderNames;
|
List<String>? senderNames;
|
||||||
List<String>? usedKeys;
|
List<String>? usedKeys;
|
||||||
List<int>? priority;
|
List<int>? priority;
|
||||||
DateTime? timeBefore;
|
DateTime? timeBefore;
|
||||||
DateTime? timeAfter;
|
DateTime? timeAfter;
|
||||||
|
bool? hasSenderName;
|
||||||
|
|
||||||
MessageFilter({
|
MessageFilter({
|
||||||
this.channelIDs,
|
this.channelIDs,
|
||||||
@ -54,7 +55,7 @@ class APIClient {
|
|||||||
required String name,
|
required String name,
|
||||||
required String method,
|
required String method,
|
||||||
required String relURL,
|
required String relURL,
|
||||||
Map<String, String>? query,
|
Map<String, Iterable<String>>? query,
|
||||||
required T Function(Map<String, dynamic> json)? fn,
|
required T Function(Map<String, dynamic> json)? fn,
|
||||||
dynamic jsonBody,
|
dynamic jsonBody,
|
||||||
String? authToken,
|
String? authToken,
|
||||||
@ -66,7 +67,7 @@ class APIClient {
|
|||||||
|
|
||||||
final req = http.Request(method, uri);
|
final req = http.Request(method, uri);
|
||||||
|
|
||||||
print('[REQUEST|RUN] [${method}] ${name}');
|
print('[REQUEST|RUN] [${method}] ${name} | ${uri.toString()}');
|
||||||
|
|
||||||
if (jsonBody != null) {
|
if (jsonBody != null) {
|
||||||
req.body = jsonEncode(jsonBody);
|
req.body = jsonEncode(jsonBody);
|
||||||
@ -206,7 +207,9 @@ class APIClient {
|
|||||||
name: 'getChannelList',
|
name: 'getChannelList',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
relURL: 'users/${auth.getUserID()}/channels',
|
relURL: 'users/${auth.getUserID()}/channels',
|
||||||
query: {'selector': sel.apiKey},
|
query: {
|
||||||
|
'selector': [sel.apiKey]
|
||||||
|
},
|
||||||
fn: (json) => ChannelWithSubscription.fromJsonArray(json['channels'] as List<dynamic>),
|
fn: (json) => ChannelWithSubscription.fromJsonArray(json['channels'] as List<dynamic>),
|
||||||
authToken: auth.getToken(),
|
authToken: auth.getToken(),
|
||||||
);
|
);
|
||||||
@ -252,14 +255,16 @@ class APIClient {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
relURL: 'messages',
|
relURL: 'messages',
|
||||||
query: {
|
query: {
|
||||||
'next_page_token': pageToken,
|
'next_page_token': [pageToken],
|
||||||
if (pageSize != null) 'page_size': pageSize.toString(),
|
if (pageSize != null) 'page_size': [pageSize.toString()],
|
||||||
if (filter?.channelIDs != null) 'channel_id': filter!.channelIDs!.join(","),
|
if (filter?.searchFilter != null) 'search': filter!.searchFilter!,
|
||||||
if (filter?.senderNames != null) 'sender': filter!.senderNames!.join(","),
|
if (filter?.channelIDs != null) 'channel_id': filter!.channelIDs!,
|
||||||
if (filter?.timeBefore != null) 'before': filter!.timeBefore!.toIso8601String(),
|
if (filter?.senderNames != null) 'sender': filter!.senderNames!,
|
||||||
if (filter?.timeAfter != null) 'after': filter!.timeAfter!.toIso8601String(),
|
if (filter?.hasSenderName != null) 'has_sender': [filter!.hasSenderName!.toString()],
|
||||||
if (filter?.priority != null) 'priority': filter!.priority!.map((p) => p.toString()).join(","),
|
if (filter?.timeBefore != null) 'before': [filter!.timeBefore!.toIso8601String()],
|
||||||
if (filter?.usedKeys != null) 'used_key': filter!.usedKeys!.join(","),
|
if (filter?.timeAfter != null) 'after': [filter!.timeAfter!.toIso8601String()],
|
||||||
|
if (filter?.priority != null) 'priority': filter!.priority!.map((p) => p.toString()).toList(),
|
||||||
|
if (filter?.usedKeys != null) 'used_key': filter!.usedKeys!,
|
||||||
},
|
},
|
||||||
fn: (json) => SCNMessage.fromPaginatedJsonArray(json, 'messages', 'next_page_token'),
|
fn: (json) => SCNMessage.fromPaginatedJsonArray(json, 'messages', 'next_page_token'),
|
||||||
authToken: auth.getToken(),
|
authToken: auth.getToken(),
|
||||||
@ -271,7 +276,6 @@ class APIClient {
|
|||||||
name: 'getMessage',
|
name: 'getMessage',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
relURL: 'messages/$msgid',
|
relURL: 'messages/$msgid',
|
||||||
query: {},
|
|
||||||
fn: SCNMessage.fromJson,
|
fn: SCNMessage.fromJson,
|
||||||
authToken: auth.getToken(),
|
authToken: auth.getToken(),
|
||||||
);
|
);
|
||||||
|
@ -66,7 +66,7 @@ class APIError {
|
|||||||
factory APIError.fromJson(Map<String, dynamic> json) {
|
factory APIError.fromJson(Map<String, dynamic> json) {
|
||||||
return APIError(
|
return APIError(
|
||||||
success: json['success'] as bool,
|
success: json['success'] as bool,
|
||||||
error: (json['error'] as double).toInt(),
|
error: (json['error'] as num).toInt(),
|
||||||
errhighlight: json['errhighlight'] as String,
|
errhighlight: json['errhighlight'] as String,
|
||||||
message: json['message'] as String,
|
message: json['message'] as String,
|
||||||
);
|
);
|
||||||
|
@ -60,6 +60,7 @@ class DebugRequestViewPage extends StatelessWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Clipboard.setData(new ClipboardData(text: title));
|
Clipboard.setData(new ClipboardData(text: title));
|
||||||
Toaster.info("Clipboard", 'Copied text to Clipboard');
|
Toaster.info("Clipboard", 'Copied text to Clipboard');
|
||||||
|
print('================= [CLIPBOARD] =================\n${title}\n================= [/CLIPBOARD] =================');
|
||||||
},
|
},
|
||||||
icon: FontAwesomeIcons.copy,
|
icon: FontAwesomeIcons.copy,
|
||||||
),
|
),
|
||||||
|
@ -308,7 +308,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
|||||||
|
|
||||||
var chipletsSearch = _filterChiplets.where((p) => p.type == MessageFilterChipletType.search).toList();
|
var chipletsSearch = _filterChiplets.where((p) => p.type == MessageFilterChipletType.search).toList();
|
||||||
if (chipletsSearch.isNotEmpty) {
|
if (chipletsSearch.isNotEmpty) {
|
||||||
filter.searchFilter = chipletsSearch.map((p) => p.value as String).first;
|
filter.searchFilter = chipletsSearch.map((p) => p.value as String).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
var chipletsKeyTokens = _filterChiplets.where((p) => p.type == MessageFilterChipletType.sendkey).toList();
|
var chipletsKeyTokens = _filterChiplets.where((p) => p.type == MessageFilterChipletType.sendkey).toList();
|
||||||
|
@ -239,6 +239,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Clipboard.setData(new ClipboardData(text: message.content ?? ''));
|
Clipboard.setData(new ClipboardData(text: message.content ?? ''));
|
||||||
Toaster.info("Clipboard", 'Copied text to Clipboard');
|
Toaster.info("Clipboard", 'Copied text to Clipboard');
|
||||||
|
print('================= [CLIPBOARD] =================\n${message.content}\n================= [/CLIPBOARD] =================');
|
||||||
},
|
},
|
||||||
icon: FontAwesomeIcons.copy,
|
icon: FontAwesomeIcons.copy,
|
||||||
),
|
),
|
||||||
|
@ -39,7 +39,8 @@ func (h APIHandler) ListMessages(pctx ginext.PreContext) ginext.HTTPResponse {
|
|||||||
type query struct {
|
type query struct {
|
||||||
PageSize *int `json:"page_size" form:"page_size"`
|
PageSize *int `json:"page_size" form:"page_size"`
|
||||||
NextPageToken *string `json:"next_page_token" form:"next_page_token"`
|
NextPageToken *string `json:"next_page_token" form:"next_page_token"`
|
||||||
Filter *string `json:"filter" form:"filter"`
|
Search []string `json:"search" form:"search"`
|
||||||
|
StringSearch []string `json:"string_search" form:"string_search"`
|
||||||
Trimmed *bool `json:"trimmed" form:"trimmed"`
|
Trimmed *bool `json:"trimmed" form:"trimmed"`
|
||||||
Channels []string `json:"channel" form:"channel"`
|
Channels []string `json:"channel" form:"channel"`
|
||||||
ChannelIDs []string `json:"channel_id" form:"channel_id"`
|
ChannelIDs []string `json:"channel_id" form:"channel_id"`
|
||||||
@ -92,8 +93,12 @@ func (h APIHandler) ListMessages(pctx ginext.PreContext) ginext.HTTPResponse {
|
|||||||
ConfirmedSubscriptionBy: langext.Ptr(userid),
|
ConfirmedSubscriptionBy: langext.Ptr(userid),
|
||||||
}
|
}
|
||||||
|
|
||||||
if q.Filter != nil && strings.TrimSpace(*q.Filter) != "" {
|
if len(q.Search) != 0 {
|
||||||
filter.SearchString = langext.Ptr([]string{strings.TrimSpace(*q.Filter)})
|
filter.SearchStringFTS = langext.Ptr(langext.ArrMap(q.Search, func(v string) string { return strings.TrimSpace(v) }))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(q.StringSearch) != 0 {
|
||||||
|
filter.SearchStringPlain = langext.Ptr(langext.ArrMap(q.StringSearch, func(v string) string { return strings.TrimSpace(v) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(q.Channels) != 0 {
|
if len(q.Channels) != 0 {
|
||||||
|
@ -15,7 +15,8 @@ import (
|
|||||||
|
|
||||||
type MessageFilter struct {
|
type MessageFilter struct {
|
||||||
ConfirmedSubscriptionBy *UserID
|
ConfirmedSubscriptionBy *UserID
|
||||||
SearchString *[]string
|
SearchStringFTS *[]string
|
||||||
|
SearchStringPlain *[]string
|
||||||
Sender *[]UserID
|
Sender *[]UserID
|
||||||
ChannelNameCS *[]string // case-sensitive
|
ChannelNameCS *[]string // case-sensitive
|
||||||
ChannelNameCI *[]string // case-insensitive
|
ChannelNameCI *[]string // case-insensitive
|
||||||
@ -49,7 +50,7 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
if f.ConfirmedSubscriptionBy != nil {
|
if f.ConfirmedSubscriptionBy != nil {
|
||||||
joinClause += " LEFT JOIN subscriptions AS subs on messages.channel_id = subs.channel_id "
|
joinClause += " LEFT JOIN subscriptions AS subs on messages.channel_id = subs.channel_id "
|
||||||
}
|
}
|
||||||
if f.SearchString != nil {
|
if f.SearchStringFTS != nil {
|
||||||
joinClause += " JOIN messages_fts AS mfts on (mfts.rowid = messages.rowid) "
|
joinClause += " JOIN messages_fts AS mfts on (mfts.rowid = messages.rowid) "
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,60 +67,53 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if f.ConfirmedSubscriptionBy != nil {
|
if f.ConfirmedSubscriptionBy != nil {
|
||||||
sqlClauses = append(sqlClauses, "(subs.subscriber_user_id = :sub_uid AND subs.confirmed = 1)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(subs.subscriber_user_id = :%s AND subs.confirmed = 1)", params.Add(*f.ConfirmedSubscriptionBy)))
|
||||||
params["sub_uid"] = *f.ConfirmedSubscriptionBy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Sender != nil {
|
if f.Sender != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.Sender {
|
for _, v := range *f.Sender {
|
||||||
filter = append(filter, fmt.Sprintf("(sender_user_id = :sender_%d)", i))
|
filter = append(filter, fmt.Sprintf("(sender_user_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("sender_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ChannelNameCI != nil {
|
if f.ChannelNameCI != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.ChannelNameCI {
|
for _, v := range *f.ChannelNameCI {
|
||||||
filter = append(filter, fmt.Sprintf("(messages.channel_internal_name = :channelnameci_%d COLLATE NOCASE)", i))
|
filter = append(filter, fmt.Sprintf("(messages.channel_internal_name = :%s COLLATE NOCASE)", params.Add(v)))
|
||||||
params[fmt.Sprintf("channelnameci_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ChannelNameCS != nil {
|
if f.ChannelNameCS != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.ChannelNameCS {
|
for _, v := range *f.ChannelNameCS {
|
||||||
filter = append(filter, fmt.Sprintf("(messages.channel_internal_name = :channelnamecs_%d COLLATE BINARY)", i))
|
filter = append(filter, fmt.Sprintf("(messages.channel_internal_name = :%s COLLATE BINARY)", params.Add(v)))
|
||||||
params[fmt.Sprintf("channelnamecs_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ChannelID != nil {
|
if f.ChannelID != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.ChannelID {
|
for _, v := range *f.ChannelID {
|
||||||
filter = append(filter, fmt.Sprintf("(messages.channel_id = :channelid_%d)", i))
|
filter = append(filter, fmt.Sprintf("(messages.channel_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("channelid_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SenderNameCI != nil {
|
if f.SenderNameCI != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.SenderNameCI {
|
for _, v := range *f.SenderNameCI {
|
||||||
filter = append(filter, fmt.Sprintf("(sender_name = :sendernameci_%d COLLATE NOCASE)", i))
|
filter = append(filter, fmt.Sprintf("(sender_name = :%s COLLATE NOCASE)", params.Add(v)))
|
||||||
params[fmt.Sprintf("sendernameci_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "(sender_name IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))")
|
sqlClauses = append(sqlClauses, "(sender_name IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SenderNameCS != nil {
|
if f.SenderNameCS != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.SenderNameCS {
|
for _, v := range *f.SenderNameCS {
|
||||||
filter = append(filter, fmt.Sprintf("(sender_name = :sendernamecs_%d COLLATE BINARY)", i))
|
filter = append(filter, fmt.Sprintf("(sender_name = :%s COLLATE BINARY)", params.Add(v)))
|
||||||
params[fmt.Sprintf("sendernamecs_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "(sender_name IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))")
|
sqlClauses = append(sqlClauses, "(sender_name IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))")
|
||||||
}
|
}
|
||||||
@ -134,66 +128,54 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
|
|
||||||
if f.SenderIP != nil {
|
if f.SenderIP != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.SenderIP {
|
for _, v := range *f.SenderIP {
|
||||||
filter = append(filter, fmt.Sprintf("(sender_ip = :senderip_%d)", i))
|
filter = append(filter, fmt.Sprintf("(sender_ip = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("senderip_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampCoalesce != nil {
|
if f.TimestampCoalesce != nil {
|
||||||
sqlClauses = append(sqlClauses, "(COALESCE(timestamp_client, timestamp_real) = :ts_equals)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(COALESCE(timestamp_client, timestamp_real) = :%s)", params.Add((*f.TimestampCoalesce).UnixMilli())))
|
||||||
params["ts_equals"] = (*f.TimestampCoalesce).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampCoalesceAfter != nil {
|
if f.TimestampCoalesceAfter != nil {
|
||||||
sqlClauses = append(sqlClauses, "(COALESCE(timestamp_client, timestamp_real) > :ts_after)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(COALESCE(timestamp_client, timestamp_real) > :%s)", params.Add((*f.TimestampCoalesceAfter).UnixMilli())))
|
||||||
params["ts_after"] = (*f.TimestampCoalesceAfter).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampCoalesceBefore != nil {
|
if f.TimestampCoalesceBefore != nil {
|
||||||
sqlClauses = append(sqlClauses, "(COALESCE(timestamp_client, timestamp_real) < :ts_before)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(COALESCE(timestamp_client, timestamp_real) < :%s)", params.Add((*f.TimestampCoalesceBefore).UnixMilli())))
|
||||||
params["ts_before"] = (*f.TimestampCoalesceBefore).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampReal != nil {
|
if f.TimestampReal != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_real = :ts_real_equals)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_real = :%s)", params.Add((*f.TimestampRealAfter).UnixMilli())))
|
||||||
params["ts_real_equals"] = (*f.TimestampRealAfter).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampRealAfter != nil {
|
if f.TimestampRealAfter != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_real > :ts_real_after)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_real > :%s)", params.Add((*f.TimestampRealAfter).UnixMilli())))
|
||||||
params["ts_real_after"] = (*f.TimestampRealAfter).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampRealBefore != nil {
|
if f.TimestampRealBefore != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_real < :ts_real_before)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_real < :%s)", params.Add((*f.TimestampRealBefore).UnixMilli())))
|
||||||
params["ts_real_before"] = (*f.TimestampRealBefore).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampClient != nil {
|
if f.TimestampClient != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_client IS NOT NULL AND timestamp_client = :ts_client_equals)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_client IS NOT NULL AND timestamp_client = :%s)", params.Add((*f.TimestampClient).UnixMilli())))
|
||||||
params["ts_client_equals"] = (*f.TimestampClient).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampClientAfter != nil {
|
if f.TimestampClientAfter != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_client IS NOT NULL AND timestamp_client > :ts_client_after)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_client IS NOT NULL AND timestamp_client > :%s)", params.Add((*f.TimestampClientAfter).UnixMilli())))
|
||||||
params["ts_client_after"] = (*f.TimestampClientAfter).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampClientBefore != nil {
|
if f.TimestampClientBefore != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_client IS NOT NULL AND timestamp_client < :ts_client_before)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_client IS NOT NULL AND timestamp_client < :%s)", params.Add((*f.TimestampClientBefore).UnixMilli())))
|
||||||
params["ts_client_before"] = (*f.TimestampClientBefore).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TitleCI != nil {
|
if f.TitleCI != nil {
|
||||||
sqlClauses = append(sqlClauses, "(title = :titleci COLLATE NOCASE)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(title = :%s COLLATE NOCASE)", params.Add(*f.TitleCI)))
|
||||||
params["titleci"] = *f.TitleCI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TitleCS != nil {
|
if f.TitleCS != nil {
|
||||||
sqlClauses = append(sqlClauses, "(title = :titleci COLLATE BINARY)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(title = :%s COLLATE BINARY)", params.Add(*f.TitleCI)))
|
||||||
params["titleci"] = *f.TitleCI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Priority != nil {
|
if f.Priority != nil {
|
||||||
@ -203,9 +185,8 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
|
|
||||||
if f.UserMessageID != nil {
|
if f.UserMessageID != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.UserMessageID {
|
for _, v := range *f.UserMessageID {
|
||||||
filter = append(filter, fmt.Sprintf("(usr_message_id = :usermessageid_%d)", i))
|
filter = append(filter, fmt.Sprintf("(usr_message_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("usermessageid_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "(usr_message_id IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))")
|
sqlClauses = append(sqlClauses, "(usr_message_id IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))")
|
||||||
}
|
}
|
||||||
@ -222,18 +203,28 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
|
|
||||||
if f.UsedKeyID != nil {
|
if f.UsedKeyID != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.UsedKeyID {
|
for _, v := range *f.UsedKeyID {
|
||||||
filter = append(filter, fmt.Sprintf("(used_key_id = :usedkeyid_%d)", i))
|
filter = append(filter, fmt.Sprintf("(used_key_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("usedkeyid_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SearchString != nil {
|
if f.SearchStringFTS != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.SearchString {
|
for _, v := range *f.SearchStringFTS {
|
||||||
filter = append(filter, fmt.Sprintf("(messages_fts match :searchstring_%d)", i))
|
filter = append(filter, fmt.Sprintf("(messages_fts match :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("searchstring_%d", i)] = v
|
}
|
||||||
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.SearchStringPlain != nil {
|
||||||
|
filter := make([]string, 0)
|
||||||
|
for _, v := range *f.SearchStringPlain {
|
||||||
|
filter = append(filter, fmt.Sprintf("instr(lower(messages.channel_internal_name), lower(:%s))", params.Add(v)))
|
||||||
|
filter = append(filter, fmt.Sprintf("instr(lower(messages.sender_name), lower(:%s))", params.Add(v)))
|
||||||
|
filter = append(filter, fmt.Sprintf("instr(lower(messages.title), lower(:%s))", params.Add(v)))
|
||||||
|
filter = append(filter, fmt.Sprintf("instr(lower(messages.content), lower(:%s))", params.Add(v)))
|
||||||
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
@ -34,52 +34,45 @@ func (f SubscriptionFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
params := sq.PP{}
|
params := sq.PP{}
|
||||||
|
|
||||||
if f.AnyUserID != nil {
|
if f.AnyUserID != nil {
|
||||||
sqlClauses = append(sqlClauses, "(subscriber_user_id = :anyuid1 OR channel_owner_user_id = :anyuid2)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(subscriber_user_id = :%s OR channel_owner_user_id = :%s)", params.Add(*f.AnyUserID), params.Add(*f.AnyUserID)))
|
||||||
params["anyuid1"] = *f.AnyUserID
|
|
||||||
params["anyuid2"] = *f.AnyUserID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SubscriberUserID != nil {
|
if f.SubscriberUserID != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.SubscriberUserID {
|
for _, v := range *f.SubscriberUserID {
|
||||||
filter = append(filter, fmt.Sprintf("(subscriber_user_id = :subscriber_uid_1_%d)", i))
|
filter = append(filter, fmt.Sprintf("(subscriber_user_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("subscriber_uid_1_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SubscriberUserID2 != nil {
|
if f.SubscriberUserID2 != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.SubscriberUserID2 {
|
for _, v := range *f.SubscriberUserID2 {
|
||||||
filter = append(filter, fmt.Sprintf("(subscriber_user_id = :subscriber_uid_2_%d)", i))
|
filter = append(filter, fmt.Sprintf("(subscriber_user_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("subscriber_uid_2_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ChannelOwnerUserID != nil {
|
if f.ChannelOwnerUserID != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.ChannelOwnerUserID {
|
for _, v := range *f.ChannelOwnerUserID {
|
||||||
filter = append(filter, fmt.Sprintf("(channel_owner_user_id = :chanowner_uid_1_%d)", i))
|
filter = append(filter, fmt.Sprintf("(channel_owner_user_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("chanowner_uid_1_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ChannelOwnerUserID2 != nil {
|
if f.ChannelOwnerUserID2 != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.ChannelOwnerUserID2 {
|
for _, v := range *f.ChannelOwnerUserID2 {
|
||||||
filter = append(filter, fmt.Sprintf("(channel_owner_user_id = :chanowner_uid_2_%d)", i))
|
filter = append(filter, fmt.Sprintf("(channel_owner_user_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("chanowner_uid_2_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ChannelID != nil {
|
if f.ChannelID != nil {
|
||||||
filter := make([]string, 0)
|
filter := make([]string, 0)
|
||||||
for i, v := range *f.ChannelID {
|
for _, v := range *f.ChannelID {
|
||||||
filter = append(filter, fmt.Sprintf("(channel_id = :chanid_%d)", i))
|
filter = append(filter, fmt.Sprintf("(channel_id = :%s)", params.Add(v)))
|
||||||
params[fmt.Sprintf("chanid_%d", i)] = v
|
|
||||||
}
|
}
|
||||||
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")")
|
||||||
}
|
}
|
||||||
@ -101,18 +94,15 @@ func (f SubscriptionFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if f.Timestamp != nil {
|
if f.Timestamp != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_created = :ts_equals)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_created = :%s)", params.Add((*f.Timestamp).UnixMilli())))
|
||||||
params["ts_equals"] = (*f.Timestamp).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampAfter != nil {
|
if f.TimestampAfter != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_created > :ts_after)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_created > :%s)", params.Add((*f.TimestampAfter).UnixMilli())))
|
||||||
params["ts_after"] = (*f.TimestampAfter).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.TimestampBefore != nil {
|
if f.TimestampBefore != nil {
|
||||||
sqlClauses = append(sqlClauses, "(timestamp_created < :ts_before)")
|
sqlClauses = append(sqlClauses, fmt.Sprintf("(timestamp_created < ::%s)", params.Add((*f.TimestampBefore).UnixMilli())))
|
||||||
params["ts_before"] = (*f.TimestampBefore).UnixMilli()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlClause := ""
|
sqlClause := ""
|
||||||
|
@ -38,7 +38,7 @@ func TestSearchMessageFTSSimple(t *testing.T) {
|
|||||||
Messages []msg `json:"messages"`
|
Messages []msg `json:"messages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/messages?filter=%s", url.QueryEscape("Friday")))
|
msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("Friday")))
|
||||||
tt.AssertEqual(t, "msgList.len", 2, len(msgList.Messages))
|
tt.AssertEqual(t, "msgList.len", 2, len(msgList.Messages))
|
||||||
tt.AssertArrAny(t, "msgList.any<1>", msgList.Messages, func(msg msg) bool { return msg.Title == "Invitation" })
|
tt.AssertArrAny(t, "msgList.any<1>", msgList.Messages, func(msg msg) bool { return msg.Title == "Invitation" })
|
||||||
tt.AssertArrAny(t, "msgList.any<2>", msgList.Messages, func(msg msg) bool { return msg.Title == "Important notice" })
|
tt.AssertArrAny(t, "msgList.any<2>", msgList.Messages, func(msg msg) bool { return msg.Title == "Important notice" })
|
||||||
@ -101,7 +101,7 @@ func TestSearchMessageFTSMulti(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/messages?used_key=%s&used_key=%s&channel=%s&filter=%s", skey, akey, "main", url.QueryEscape("tomorrow")))
|
msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/messages?used_key=%s&used_key=%s&channel=%s&search=%s", skey, akey, "main", url.QueryEscape("tomorrow")))
|
||||||
tt.AssertEqual(t, "msgList.len", 1, len(msgList.Messages))
|
tt.AssertEqual(t, "msgList.len", 1, len(msgList.Messages))
|
||||||
tt.AssertEqual(t, "msg.Title", "Notice", msgList.Messages[0].Title)
|
tt.AssertEqual(t, "msg.Title", "Notice", msgList.Messages[0].Title)
|
||||||
}
|
}
|
||||||
@ -699,7 +699,7 @@ func TestListMessagesZeroPagesize(t *testing.T) {
|
|||||||
tt.AssertEqual(t, "msgList[0]", "Lorem Ipsum 23", msgList1.Messages[0].Title)
|
tt.AssertEqual(t, "msgList[0]", "Lorem Ipsum 23", msgList1.Messages[0].Title)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListMessagesFilterChannel(t *testing.T) {
|
func TestListMessagesFiltered(t *testing.T) {
|
||||||
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
defer stop()
|
defer stop()
|
||||||
|
|
||||||
@ -763,8 +763,8 @@ func TestListMessagesFilterChannel(t *testing.T) {
|
|||||||
{"channel=Reminders", 6, fmt.Sprintf("/api/v2/messages?channel=%s", "Reminders")},
|
{"channel=Reminders", 6, fmt.Sprintf("/api/v2/messages?channel=%s", "Reminders")},
|
||||||
{"channel_id=1", 6, fmt.Sprintf("/api/v2/messages?channel_id=%s", cid1)},
|
{"channel_id=1", 6, fmt.Sprintf("/api/v2/messages?channel_id=%s", cid1)},
|
||||||
{"channel_id=1|2", 9, fmt.Sprintf("/api/v2/messages?channel_id=%s&channel_id=%s", cid1, cid2)},
|
{"channel_id=1|2", 9, fmt.Sprintf("/api/v2/messages?channel_id=%s&channel_id=%s", cid1, cid2)},
|
||||||
{"filter=unusual", 1, fmt.Sprintf("/api/v2/messages?filter=%s", "unusual")},
|
{"search=unusual", 1, fmt.Sprintf("/api/v2/messages?search=%s", "unusual")},
|
||||||
{"filter=your", 6, fmt.Sprintf("/api/v2/messages?filter=%s", "your")},
|
{"search=your", 6, fmt.Sprintf("/api/v2/messages?search=%s", "your")},
|
||||||
{"prio=0", 5, fmt.Sprintf("/api/v2/messages?priority=%s", "0")},
|
{"prio=0", 5, fmt.Sprintf("/api/v2/messages?priority=%s", "0")},
|
||||||
{"prio=1", 4 + 7, fmt.Sprintf("/api/v2/messages?priority=%s", "1")},
|
{"prio=1", 4 + 7, fmt.Sprintf("/api/v2/messages?priority=%s", "1")},
|
||||||
{"prio=2", 6, fmt.Sprintf("/api/v2/messages?priority=%s", "2")},
|
{"prio=2", 6, fmt.Sprintf("/api/v2/messages?priority=%s", "2")},
|
||||||
@ -790,3 +790,115 @@ func TestListMessagesFilterChannel(t *testing.T) {
|
|||||||
tt.AssertEqual(t, "msgList.filter["+testdata.Name+"].len", testdata.Count, msgList.TotalCount)
|
tt.AssertEqual(t, "msgList.filter["+testdata.Name+"].len", testdata.Count, msgList.TotalCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListMessagesSearch(t *testing.T) {
|
||||||
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
|
defer stop()
|
||||||
|
|
||||||
|
data := tt.InitDefaultData(t, ws)
|
||||||
|
|
||||||
|
type msg struct {
|
||||||
|
ChannelId string `json:"channel_id"`
|
||||||
|
ChannelInternalName string `json:"channel_internal_name"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
MessageId string `json:"message_id"`
|
||||||
|
OwnerUserId string `json:"owner_user_id"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
SenderIp string `json:"sender_ip"`
|
||||||
|
SenderName string `json:"sender_name"`
|
||||||
|
SenderUserId string `json:"sender_user_id"`
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Trimmed bool `json:"trimmed"`
|
||||||
|
UsrMessageId string `json:"usr_message_id"`
|
||||||
|
}
|
||||||
|
type mglist struct {
|
||||||
|
Messages []msg `json:"messages"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
filterTests := []struct {
|
||||||
|
Name string
|
||||||
|
Count int
|
||||||
|
Query string
|
||||||
|
}{
|
||||||
|
{"all", 22, fmt.Sprintf("/api/v2/messages")},
|
||||||
|
|
||||||
|
{"search=Promotions", 3, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("Promotions"))},
|
||||||
|
{"search=Important(1)", 3, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("Important"))},
|
||||||
|
{"search=Important(2)", 3, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("important"))},
|
||||||
|
{"search=Important(3)", 3, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("IMPORTANT"))},
|
||||||
|
{"search=safetyTraining(1)", 1, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("safety training"))},
|
||||||
|
{"search=safetyTraining(2)", 1, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("\"safety training\""))},
|
||||||
|
{"search=staffMeeting(1)", 2, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("staff meeting"))},
|
||||||
|
{"search=staffMeeting(2)", 1, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("\"staff meeting\""))},
|
||||||
|
{"search=?", 0, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("\"?\""))}, // fails because FTS searches for full words
|
||||||
|
{"search=Prom", 0, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("Prom"))}, // fails because FTS searches for full words
|
||||||
|
{"search=the(1)", 17, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("the"))},
|
||||||
|
{"search=the(2)", 17, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("THE"))},
|
||||||
|
{"search=please", 9, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("please"))},
|
||||||
|
{"search=11pm", 2, fmt.Sprintf("/api/v2/messages?search=%s", url.QueryEscape("\"11:00pm\""))},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testdata := range filterTests {
|
||||||
|
msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, testdata.Query)
|
||||||
|
tt.AssertEqual(t, "msgList.filter["+testdata.Name+"].len", testdata.Count, msgList.TotalCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListMessagesStringSearch(t *testing.T) {
|
||||||
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
|
defer stop()
|
||||||
|
|
||||||
|
data := tt.InitDefaultData(t, ws)
|
||||||
|
|
||||||
|
type msg struct {
|
||||||
|
ChannelId string `json:"channel_id"`
|
||||||
|
ChannelInternalName string `json:"channel_internal_name"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
MessageId string `json:"message_id"`
|
||||||
|
OwnerUserId string `json:"owner_user_id"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
SenderIp string `json:"sender_ip"`
|
||||||
|
SenderName string `json:"sender_name"`
|
||||||
|
SenderUserId string `json:"sender_user_id"`
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Trimmed bool `json:"trimmed"`
|
||||||
|
UsrMessageId string `json:"usr_message_id"`
|
||||||
|
}
|
||||||
|
type mglist struct {
|
||||||
|
Messages []msg `json:"messages"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
filterTests := []struct {
|
||||||
|
Name string
|
||||||
|
Count int
|
||||||
|
Query string
|
||||||
|
}{
|
||||||
|
{"all", 22, fmt.Sprintf("/api/v2/messages")},
|
||||||
|
|
||||||
|
{"search=Promotions", 3, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("Promotions"))},
|
||||||
|
{"search=Important(1)", 3, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("Important"))},
|
||||||
|
{"search=Important(2)", 3, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("important"))},
|
||||||
|
{"search=Important(3)", 3, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("IMPORTANT"))},
|
||||||
|
{"search=safetyTraining", 1, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("safety training"))},
|
||||||
|
{"search=?", 1, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("?"))},
|
||||||
|
{"search=the(1)", 17, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("the"))},
|
||||||
|
{"search=the(2)", 17, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("THE"))},
|
||||||
|
{"search=please", 9, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("please"))},
|
||||||
|
{"search=there", 3, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("tHERe"))},
|
||||||
|
{"search=11pm", 2, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("11:00pm"))},
|
||||||
|
|
||||||
|
{"search=Prom", 3, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("Prom"))},
|
||||||
|
{"search=run", 1, fmt.Sprintf("/api/v2/messages?string_search=%s", url.QueryEscape("run"))},
|
||||||
|
|
||||||
|
{"search=please+there", 10, fmt.Sprintf("/api/v2/messages?string_search=%s&string_search=%s", url.QueryEscape("please"), url.QueryEscape("THERE"))},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testdata := range filterTests {
|
||||||
|
msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, testdata.Query)
|
||||||
|
tt.AssertEqual(t, "msgList.filter["+testdata.Name+"].len", testdata.Count, msgList.TotalCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -139,7 +139,7 @@ var messageExamples = []msgex{
|
|||||||
{0, "", "", P0, SKEY, "Deadline reminder", "Please remember to submit your project proposal by the end of the day \U0001f638", 0},
|
{0, "", "", P0, SKEY, "Deadline reminder", "Please remember to submit your project proposal by the end of the day \U0001f638", 0},
|
||||||
{0, "Reminders", "", PX, AKEY, "Attention - The copier is out of toner", "", 0},
|
{0, "Reminders", "", PX, AKEY, "Attention - The copier is out of toner", "", 0},
|
||||||
{0, "Reminders", "Cellular Confidant", P2, SKEY, "Reminder", "Don't forget to clock in before starting your shift", timeext.FromHours(0.40)},
|
{0, "Reminders", "Cellular Confidant", P2, SKEY, "Reminder", "Don't forget to clock in before starting your shift", timeext.FromHours(0.40)},
|
||||||
{0, "Reminders", "Cellular Confidant", P1, AKEY, "Important", "There will be a company-wide meeting on Monday at 9:00am in the conference room", timeext.FromHours(23.15)},
|
{0, "Reminders", "Cellular Confidant", P1, AKEY, "Important", "There will be a company-wide meeting on Monday at 9:00am in the conference room, all staff must attend", timeext.FromHours(23.15)},
|
||||||
{0, "", "", P2, SKEY, "System update", "We will be performing maintenance on the server tonight at 11:00pm. The system may be unavailable for up to an hour. Please save any unsaved work before then", 0},
|
{0, "", "", P2, SKEY, "System update", "We will be performing maintenance on the server tonight at 11:00pm. The system may be unavailable for up to an hour. Please save any unsaved work before then", 0},
|
||||||
{0, "Promotions", "Pocket Pal", P0, SKEY, "Attention - The first aid kit is running low on supplies.", "", 0},
|
{0, "Promotions", "Pocket Pal", P0, SKEY, "Attention - The first aid kit is running low on supplies.", "", 0},
|
||||||
{0, "Promotions", "Pocket Pal", PX, AKEY, "Urgent", "We have received a complaint about a safety hazard in the workplace. Please address the issue immediately", 0},
|
{0, "Promotions", "Pocket Pal", PX, AKEY, "Urgent", "We have received a complaint about a safety hazard in the workplace. Please address the issue immediately", 0},
|
||||||
|
Loading…
Reference in New Issue
Block a user