Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions spec/src/modules/quizzes.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,104 @@ describe(`ConstructorIO - Quizzes${bundledDescriptionSuffix}`, () => {
fetchSpy = null;
});

describe('getQuizAllQuestions', () => {
it('Should return a result provided a valid apiKey and quizId', () => {
const { quizzes } = new ConstructorIO({
apiKey: quizApiKey,
fetch: fetchSpy,
});

return quizzes.getQuizAllQuestions(validQuizId).then((res) => {
const requestedUrlParams = helpers.extractUrlParamsFromFetch(fetchSpy);

expect(res).to.have.property('quiz_version_id').to.be.an('string');
expect(res).to.have.property('questions').to.be.an('array');
expect(res.questions[0].id).to.equal(1);
expect(res.total_questions).to.equal(1);
expect(fetchSpy).to.have.been.called;
expect(requestedUrlParams).to.have.property('key');
expect(requestedUrlParams).to.have.property('i');
expect(requestedUrlParams).to.have.property('s');
expect(requestedUrlParams).to.have.property('c').to.equal(clientVersion);
expect(requestedUrlParams).to.have.property('_dt');
});
});

it('Should return a result provided a valid apiKey, quizId and section', () => {
const section = 'Products';
const { quizzes } = new ConstructorIO({
apiKey: quizApiKey,
fetch: fetchSpy,
});

return quizzes.getQuizAllQuestions(validQuizId, { section }).then((res) => {
const requestedUrlParams = helpers.extractUrlParamsFromFetch(fetchSpy);

expect(res).to.have.property('quiz_version_id').to.be.an('string');
expect(res).to.have.property('questions').to.be.an('array');
expect(fetchSpy).to.have.been.called;
expect(requestedUrlParams).to.have.property('section').to.equal(section);
});
});

it('Should return a result provided a valid apiKey, quizId and quizVersionId', () => {
const { quizzes } = new ConstructorIO({
apiKey: quizApiKey,
fetch: fetchSpy,
});

return quizzes.getQuizAllQuestions(validQuizId).then((initialResponse) => {
const quizVersionId = initialResponse.quiz_version_id;

return quizzes.getQuizAllQuestions(validQuizId, { quizVersionId }).then((res) => {
const requestedUrlParams = helpers.extractUrlParamsFromFetch(fetchSpy);

expect(res).to.have.property('questions').to.be.an('array');
expect(res).to.have.property('quiz_version_id').to.be.an('string').to.equal(quizVersionId);
expect(res.total_questions).to.equal(1);
expect(fetchSpy).to.have.been.called;
expect(requestedUrlParams).to.have.property('quiz_version_id').to.equal(quizVersionId);
});
});
});

it('Should error when fetching quiz questions with an invalid quizId', () => {
const { quizzes } = new ConstructorIO({
apiKey: quizApiKey,
fetch: fetchSpy,
});

return expect(quizzes.getQuizAllQuestions('invalidQuizId')).to.eventually.be.rejected;
});

it('Should error when fetching quiz questions with no quizId', () => {
const { quizzes } = new ConstructorIO({
apiKey: quizApiKey,
fetch: fetchSpy,
});

return expect(quizzes.getQuizAllQuestions(null)).to.eventually.be.rejected;
});

it('Should error when fetching quiz questions with an invalid apiKey', () => {
const { quizzes } = new ConstructorIO({
apiKey: 'invalidKey',
fetch: fetchSpy,
});

return expect(quizzes.getQuizAllQuestions(validQuizId)).to.eventually.be.rejected;
});

it('Should be rejected if an invalid quizVersionId is provided', () => {
const { quizzes } = new ConstructorIO({
apiKey: quizApiKey,
fetch: fetchSpy,
});

return expect(quizzes.getQuizAllQuestions(validQuizId, { quizVersionId: 'foo' })).to.eventually.be.rejected;
});
});

describe('getQuizNextQuestion', () => {
it('Should return a result provided a valid apiKey and quizId', () => {
const { quizzes } = new ConstructorIO({
Expand Down
46 changes: 46 additions & 0 deletions src/modules/quizzes.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,52 @@ class Quizzes {
throw new Error('getQuizResultsConfig response data is malformed');
});
}

/**
* Retrieves all questions for a particular quiz
*
* @function getQuizAllQuestions
* @description Retrieve all questions for a particular quiz from Constructor.io API
* @param {string} quizId - The identifier of the quiz
* @param {object} parameters - Additional parameters
* @param {string} [parameters.section] - Product catalog section
* @param {string} [parameters.quizVersionId] - Version identifier for the quiz. Version ID will be returned with the first request and it should be passed with subsequent requests. More information can be found: https://docs.constructor.com/reference/configuration-quizzes
* @param {string} [parameters.quizSessionId] - Session identifier for the quiz. Session ID will be returned with the first request or with getQuizResultsConfig and it should be passed with subsequent requests. More information can be found: https://docs.constructor.com/reference/configuration-quizzes
* @param {object} [networkParameters] - Parameters relevant to the network request
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
* @returns {Promise}
* @example
* constructorio.quizzes.getQuizAllQuestions('quizId', {
* quizVersionId: '123',
* });
*/
getQuizAllQuestions(quizId, parameters, networkParameters = {}) {
let requestUrl;
const { fetch } = this.options;
const controller = new AbortController();
const { signal } = controller;

try {
requestUrl = createQuizUrl(quizId, parameters, this.options, 'all_questions');
} catch (e) {
return Promise.reject(e);
}

// Handle network timeout if specified
helpers.applyNetworkTimeout(this.options, networkParameters, controller);

return fetch(requestUrl, { signal })
.then(helpers.convertResponseToJson)
.then((json) => {
if (json.quiz_version_id) {
this.eventDispatcher.queue('quizzes.getQuizAllQuestions.completed', json);

return json;
}

throw new Error('getQuizAllQuestions response data is malformed');
});
}
}

module.exports = Quizzes;
8 changes: 8 additions & 0 deletions src/types/quizzes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ export interface NextQuestionResponse extends Record<string, any> {
total_questions: number;
}

export interface AllQuestionsResponse extends Record<string, any> {
questions: Question[];
quiz_version_id?: string;
quiz_id?: string;
quiz_session_id?: string;
total_questions: number;
}

export interface QuizResultsResponse extends Record<string, any> {
request?: {
filters?: Record<string, any>;
Expand Down
Loading