Skip to content

Commit

Permalink
Fix course search for blueprint
Browse files Browse the repository at this point in the history
closes CLAB-31
flag=none

Test plan:
- Create a blueprint course
- Create a course with name: "Normal name"
- Create a course with name: "#!Special course"
- Go to blueprint course, open blueprint settings, go to associations
and try to search with string that starts "#!Sp"
- There is no error, you can find the "#!Special course"
- Searching for "Normal name" there is no regression, course can be found

Change-Id: I9f93e75d883eae754626aab0d12604fc60f3ad11
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/344951
Reviewed-by: Ferenc Marcsó <ferenc.marcso@instructure.com>
Reviewed-by: Mysti Lilla <mysti@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Kata Virag Keri <kata.keri@instructure.com>
QA-Review: Ferenc Marcsó <ferenc.marcso@instructure.com>
  • Loading branch information
viszpis committed Apr 19, 2024
1 parent 802d768 commit 22181bb
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 7 deletions.
94 changes: 94 additions & 0 deletions spec/javascripts/jsx/blueprint_courses/apiClientSpec.js
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2024 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import apiClient, {
DEFAULT_PER_PAGE_PARAM,
DEFAULT_BLUEPRINT_PARAM,
DEFAULT_BLUEPRINT_ASSOCIATED_PARAM,
DEFAULT_TERM_INCLUDE_PARAM,
DEFAULT_TEACHERS_INCLUDE_PARAM,
DEFAULT_TEACHERS_LIMIT_PARAM,
} from '@canvas/blueprint-courses/react/apiClient'
import axios from '@canvas/axios'

let sandbox = null
const mockAxiosClient = (method, res) => {
sandbox = sinon.createSandbox()
return sandbox.stub(axios, method).returns(res)
}

const mockBaseDomain = 'http://canvas.docker'
const accountParams = {accountId: 1}
const getCourseParams = {
search: 'foo',
term: 'bar',
}

QUnit.module('Blueprint Course apiClient', {
teardown() {
if (sandbox) sandbox.restore()
sandbox = null
},
})

test('getCourse generated uri', () => {
const axiosStub = mockAxiosClient('get', Promise.resolve({}))

apiClient.getCourses(accountParams, getCourseParams)

const url = new URL(axiosStub.args[0][0], mockBaseDomain)
equal(url.pathname, `/api/v1/accounts/${accountParams.accountId}/courses`)
equal(url.searchParams.get('per_page'), DEFAULT_PER_PAGE_PARAM)
equal(url.searchParams.get('blueprint'), DEFAULT_BLUEPRINT_PARAM)
equal(url.searchParams.get('blueprint_associated'), DEFAULT_BLUEPRINT_ASSOCIATED_PARAM)
equal(url.searchParams.getAll('include[]')[0], DEFAULT_TERM_INCLUDE_PARAM)
equal(url.searchParams.getAll('include[]')[1], DEFAULT_TEACHERS_INCLUDE_PARAM)
equal(url.searchParams.get('teacher_limit'), DEFAULT_TEACHERS_LIMIT_PARAM)
equal(url.searchParams.get('search_term'), getCourseParams.search)
equal(url.searchParams.get('enrollment_term_id'), getCourseParams.term)
})

test('getCourse generated uri on subAccount given', () => {
const expectedSubAccount = 'sub'
const axiosStub = mockAxiosClient('get', Promise.resolve({}))

apiClient.getCourses(accountParams, {...getCourseParams, subAccount: expectedSubAccount})

const url = new URL(axiosStub.args[0][0], mockBaseDomain)
equal(url.pathname, `/api/v1/accounts/${expectedSubAccount}/courses`)
})

test('getCourse generated uri on search contains URI reserved character', () => {
const expectedSearch = 'search#reserved'
const axiosStub = mockAxiosClient('get', Promise.resolve({}))

apiClient.getCourses(accountParams, {...getCourseParams, search: expectedSearch})

const url = new URL(axiosStub.args[0][0], mockBaseDomain)
equal(url.searchParams.get('search_term'), expectedSearch)
})

test('getCourse generated uri on search starts with URI reserved character', () => {
const expectedSearch = '#searchstring'
const axiosStub = mockAxiosClient('get', Promise.resolve({}))

apiClient.getCourses(accountParams, {...getCourseParams, search: expectedSearch})

const url = new URL(axiosStub.args[0][0], mockBaseDomain)
equal(url.searchParams.get('search_term'), expectedSearch)
})
21 changes: 14 additions & 7 deletions ui/shared/blueprint-courses/react/apiClient.js
Expand Up @@ -20,6 +20,13 @@ import axios from '@canvas/axios'
import parseLinkHeader from 'link-header-parsing/parseLinkHeaderFromAxios'
import MigrationStates from './migrationStates'

export const DEFAULT_PER_PAGE_PARAM = '100'
export const DEFAULT_BLUEPRINT_PARAM = 'false'
export const DEFAULT_BLUEPRINT_ASSOCIATED_PARAM = 'false'
export const DEFAULT_TERM_INCLUDE_PARAM = 'term'
export const DEFAULT_TEACHERS_INCLUDE_PARAM = 'teachers'
export const DEFAULT_TEACHERS_LIMIT_PARAM = '5'

const ApiClient = {
_depaginate(url, maxPages = Infinity, allResults = []) {
return axios.get(url).then(res => {
Expand Down Expand Up @@ -49,13 +56,13 @@ const ApiClient = {

getCourses({accountId}, {search = '', term = '', subAccount = ''} = {}) {
const params = this._queryString([
{per_page: '100'},
{blueprint: 'false'},
{blueprint_associated: 'false'},
{'include[]': 'term'},
{'include[]': 'teachers'},
{teacher_limit: '5'},
{search_term: search},
{per_page: DEFAULT_PER_PAGE_PARAM},
{blueprint: DEFAULT_BLUEPRINT_PARAM},
{blueprint_associated: DEFAULT_BLUEPRINT_ASSOCIATED_PARAM},
{'include[]': DEFAULT_TERM_INCLUDE_PARAM},
{'include[]': DEFAULT_TEACHERS_INCLUDE_PARAM},
{teacher_limit: DEFAULT_TEACHERS_LIMIT_PARAM},
{search_term: encodeURIComponent(search)},
{enrollment_term_id: term},
])

Expand Down

0 comments on commit 22181bb

Please sign in to comment.