mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #14288 from mvdbeek/fix_tag_autocomplete
[22.05] Fix tag autocomplete for strings that need url encoding
This commit is contained in:
@@ -57,10 +57,11 @@ export class TagService {
|
||||
if (!tag.valid) {
|
||||
throw new Error("Invalid tag");
|
||||
}
|
||||
const url = `${getAppRoot()}tag/add_tag_async?item_id=${id}&item_class=${itemClass}&context=${context}&new_tag=${
|
||||
tag.text
|
||||
}`;
|
||||
const response = await axios.get(url);
|
||||
const url = `${getAppRoot()}tag/add_tag_async`;
|
||||
const config = {
|
||||
params: { item_id: id, item_class: itemClass, context: context, new_tag: tag.text },
|
||||
};
|
||||
const response = await axios.get(url, config);
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Unable to save tag: ${tag}`);
|
||||
}
|
||||
@@ -75,10 +76,9 @@ export class TagService {
|
||||
async delete(rawTag) {
|
||||
const { id, itemClass, context } = this;
|
||||
const tag = createTag(rawTag);
|
||||
const url = `${getAppRoot()}tag/remove_tag_async?item_id=${id}&item_class=${itemClass}&context=${context}&tag_name=${
|
||||
tag.text
|
||||
}`;
|
||||
const response = await axios.get(url);
|
||||
const url = `${getAppRoot()}tag/remove_tag_async`;
|
||||
const config = { params: { item_id: id, item_class: itemClass, context: context, tag_name: tag.text } };
|
||||
const response = await axios.get(url, config);
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Unable to delete tag: ${tag}`);
|
||||
}
|
||||
@@ -92,8 +92,9 @@ export class TagService {
|
||||
*/
|
||||
async autocomplete(searchText) {
|
||||
const { id, itemClass } = this;
|
||||
const url = `${getAppRoot()}tag/tag_autocomplete_data?item_id=${id}&item_class=${itemClass}&q=${searchText}`;
|
||||
const response = await axios.get(url);
|
||||
const url = `${getAppRoot()}tag/tag_autocomplete_data`;
|
||||
const config = { params: { item_id: id, item_class: itemClass, q: searchText } };
|
||||
const response = await axios.get(url, config);
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Unable to retrieve autocomplete tags for search string: ${searchText}`);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,6 @@ import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { TagService } from "./tagService";
|
||||
import { createTag } from "./model";
|
||||
//import { interval } from "rxjs";
|
||||
//import { take, takeUntil } from "rxjs/operators";
|
||||
// test response
|
||||
import autocompleteResponse from "./testData/autocompleteResponse.txt";
|
||||
|
||||
describe("Tags/tagService.js", () => {
|
||||
@@ -15,6 +12,12 @@ describe("Tags/tagService.js", () => {
|
||||
context: "",
|
||||
debounceInterval: 50, // shorter value than default for unit tests
|
||||
};
|
||||
const testLabel = "fo0bar123";
|
||||
const expectedParams = {
|
||||
item_id: 123,
|
||||
item_class: "fooClass",
|
||||
context: "",
|
||||
};
|
||||
|
||||
const svc = new TagService(svcParams);
|
||||
beforeEach(() => {
|
||||
@@ -26,43 +29,43 @@ describe("Tags/tagService.js", () => {
|
||||
});
|
||||
|
||||
describe("save", () => {
|
||||
const testLabel = "fo0bar123";
|
||||
const testTag = createTag(testLabel);
|
||||
|
||||
const { id, itemClass, context } = svcParams;
|
||||
const expectedSaveUrl = `/tag/add_tag_async?item_id=${id}&item_class=${itemClass}&context=${context}&new_tag=${testLabel}`;
|
||||
const expectedSaveUrl = `/tag/add_tag_async`;
|
||||
|
||||
it("should save a string tag", async () => {
|
||||
const savedTag = await svc.save(testLabel);
|
||||
expect(savedTag.text).toBe(testLabel);
|
||||
expect(axiosMock.history.get[0].url).toBe(expectedSaveUrl);
|
||||
expect(axiosMock.history.get[0].params).toEqual({ ...expectedParams, new_tag: testLabel });
|
||||
});
|
||||
|
||||
it("should save an object tag", async () => {
|
||||
const savedTag = await svc.save(testTag);
|
||||
expect(savedTag.text).toBe(testLabel);
|
||||
expect(axiosMock.history.get[0].url).toBe(expectedSaveUrl);
|
||||
expect(axiosMock.history.get[0].params).toEqual({ ...expectedParams, new_tag: testLabel });
|
||||
});
|
||||
|
||||
// TODO: test error conditions
|
||||
});
|
||||
describe("delete", () => {
|
||||
const testLabel = "fo0bar123";
|
||||
const testTag = createTag(testLabel);
|
||||
|
||||
const { id, itemClass, context } = svcParams;
|
||||
const expectedDeleteUrl = `/tag/remove_tag_async?item_id=${id}&item_class=${itemClass}&context=${context}&tag_name=${testLabel}`;
|
||||
const expectedDeleteUrl = `/tag/remove_tag_async`;
|
||||
|
||||
it("should delete a text tag", async () => {
|
||||
const result = await svc.delete(testTag);
|
||||
expect(result).toBeTruthy();
|
||||
expect(axiosMock.history.get[0].url).toBe(expectedDeleteUrl);
|
||||
expect(axiosMock.history.get[0].params).toEqual({ ...expectedParams, tag_name: testLabel });
|
||||
});
|
||||
|
||||
it("should delete an object tag", async () => {
|
||||
const result = await svc.delete(testTag);
|
||||
expect(result).toBeTruthy();
|
||||
expect(axiosMock.history.get[0].url).toBe(expectedDeleteUrl);
|
||||
expect(axiosMock.history.get[0].params).toEqual({ ...expectedParams, tag_name: testLabel });
|
||||
});
|
||||
|
||||
// TODO: test error conditions
|
||||
@@ -70,8 +73,7 @@ describe("Tags/tagService.js", () => {
|
||||
|
||||
describe("autocomplete", () => {
|
||||
const searchString = "foo";
|
||||
const { id, itemClass } = svcParams;
|
||||
const expectedSearchUrl = `/tag/tag_autocomplete_data?item_id=${id}&item_class=${itemClass}&q=${searchString}`;
|
||||
const expectedSearchUrl = `/tag/tag_autocomplete_data`;
|
||||
|
||||
const checkAutocompleteResult = (result) => {
|
||||
expect(result).toBeTruthy();
|
||||
@@ -83,46 +85,14 @@ describe("Tags/tagService.js", () => {
|
||||
|
||||
// straight ajax request, unused in practice, but it's easier to
|
||||
// test this call if we just expose it
|
||||
const { ...searchParams } = expectedParams;
|
||||
delete searchParams.context;
|
||||
|
||||
it("ajax call should return tag objects", async () => {
|
||||
const result = await svc.autocomplete(searchString);
|
||||
expect(axiosMock.history.get[0].url).toBe(expectedSearchUrl);
|
||||
expect(axiosMock.history.get[0].params).toEqual({ ...searchParams, q: searchString });
|
||||
checkAutocompleteResult(result);
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
// hit the search input with multiple entries, only one ajax call
|
||||
// should result because of debouncing
|
||||
it("should debounce autocomplete search inputs", (done) => {
|
||||
// stub ajax request to return the success response if the
|
||||
// searchString is the expected input
|
||||
|
||||
// take first emission, debouncing should guarantee the first
|
||||
// emission is the last thing we sent, should be searchString
|
||||
const timer$ = interval(100).pipe(take(1));
|
||||
const option$ = svc.autocompleteOptions.pipe(takeUntil(timer$));
|
||||
|
||||
const nextHandler = jest.fn();
|
||||
|
||||
option$.subscribe({
|
||||
next: nextHandler,
|
||||
error: (err) => console.warn("error", err),
|
||||
complete: () => {
|
||||
expect(nextHandler).toHaveBeenCalledTimes(1);
|
||||
expect(axiosMock.history.get.length).toBe(1);
|
||||
done();
|
||||
},
|
||||
});
|
||||
|
||||
// spam a bunch of key inputs followed by the correct input
|
||||
const spamCount = 2 + Math.floor(Math.random() * 10);
|
||||
for (let i = 0; i < spamCount; i++) {
|
||||
const spamVal = new String(Math.random());
|
||||
svc.autocompleteSearchText = spamVal;
|
||||
}
|
||||
svc.autocompleteSearchText = searchString;
|
||||
});
|
||||
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user