Manual Reference Source Test

src/services/DiscussService.js

import Client from '../Client';
import JsonApiService from './JsonApiService';
import {
  hasAttribute,
  hasToken,
  isRequired,
  validate,
} from '../utilities/ValidationUtility';

/**
 * Service handling comment calls with specific endpoints.
 *
 * Typically this shouldn't be used directly but by using some of the other modules that support
 * comment functionality.  Currently this includes {@link Content}, {@link Flow}, {@link FlowStep},
 * {@link Profile}, {@link Question}, and {@link MobileUser}.
 */
class DiscussService extends JsonApiService {
  /**
   * Update type to be commentable__threads
   */
  constructor() {
    super();

    /** @type {String} - The type of the default data */
    this.type = 'commentable__threads';
  }

  /**
   * Get or filter threads.
   *
   * @throws {Clinical6Error}       - If missing required parameters
   * @param  {!Object}  data        - Object in which to have a discussion
   * @param  {!Number}  data.id     - Object id to start a discussion on
   * @param  {!String}  data.type   - Object type to start a discussion on
   * @param  {String}   [cacheMode] - Override the caching method for this call
   * @return {Promise<Thread[]>}      - Promise a thread
   *
   * @example
   * import { discussService } from 'clinical6';
   *
   * discussService.get();  // get all threads
   *
   * // Get threads from a flow
   * myFlow = new Flow({...});
   * discussService.get(myFlow);
   *
   * // This is also called from other objects in the system like a flow or flowstep.
   * // In this case, it will use the flow/flowstep owner and object information automatically.
   * myFlow.getThreads();
   * myFlow.first.getThreads();  // FlowStep Comments
   */
  get(data = undefined, cacheMode = undefined) {
    validate('DiscussService.get',
      hasToken());

    let httpQuery = ``;
    if (data) {
      httpQuery = `?filters[commentable_type]=${data.type}&filters[commentable_id]=${data.id}`;
    }

    const url = `/v3/discuss/threads${httpQuery}`;
    return super.get({ }, { url, cacheMode });
  }

  /**
   * Fetches comments associated to a specific object.
   *
   * @throws {Clinical6Error}       - If missing token or missing required parameters
   * @param  {!Object}  thread      - The thread having comments
   * @param  {!Number}  options.id  - The thread id
   * @param  {String}   [cacheMode] - Override the caching method for this call
   * @return {Promise<Comment[] | Comment>}
   *                                - Promise object that returns success or failure
   *
   * @example
   * import { discussService } from 'clinical6';
   *
   * const thread = new Thread({...});
   * discussService.getComments(thread);
   */
  getComments(thread, cacheMode = undefined) {
    validate('DiscussService.getComments',
      hasToken(),
      isRequired({ thread }),
      hasAttribute({ thread }, 'id'));

    const url = `/v3/discuss/threads/${thread.id}/comments`;
    return super.get({ type: 'commentable__comments' }, { url, cacheMode });
  }

  /**
   * Insert Thread
   *
   * @throws {Clinical6Error}       - If missing required parameters
   * @param  {!Object}  data        - Object in which to have a discussion
   * @param  {!Number}  data.id     - Object id to start a discussion on
   * @param  {!String}  data.type   - Object type to start a discussion on
   * @param  {String}   [cacheMode] - Override the caching method for this call
   * @return {Promise<Thread>}      - Promise a thread
   *
   * @example
   * import { discussService } from 'clinical6';
   * const thread = await discussService.insert(myFlow);
   */
  insert(data, cacheMode = undefined) {
    validate('DiscussService.insert',
      hasToken(),
      isRequired({ data }),
      hasAttribute({ data }, 'id'),
      hasAttribute({ data }, 'type'));
    const { id, type } = data;
    const params = {
      type: 'commentable__threads',
      attributes: {},
      relationships: { commentable: { data: { id, type } } }
    };

    return super.insert(params, { url: `/v3/discuss/threads`, cacheMode });
  }

  /**
   * Insert Comment
   *
   * @throws {Clinical6Error}         - If missing required parameters
   * @param  {!String}  text          - The comment text
   * @param  {!Object}  thread        - The discussion thread
   * @param  {!Number}  thread.id     - Thread id to start a discussion on
   * @param  {!String}  thread.type   - Thread type to start a discussion on
   * @param  {!Object}  [author]      - The author of the comment
   * @param  {!Number}  [author.id]   - Author id
   * @param  {!String}  [author.type] - Author type ('mobile_users' or 'users')
   * @param  {String}   [cacheMode]   - Override the caching method for this call
   * @return {Promise<Comment>}       - Promise a thread
   *
   * @example
   * import { discussService, Thread, MobileUser } from 'clinical6';
   * const thread = new Thread({...});
   * const author = new MobileUser({...});
   * const comment = await discussService.insertComment('Hello World', thread);
   */
  insertComment(text, thread, author = undefined, cacheMode = undefined) {
    const user = author || Client.instance.user;

    validate('DiscussService.insertComment',
      hasToken(),
      isRequired({ text, thread, user }),
      hasAttribute({ thread, user }, 'id'),
      hasAttribute({ thread, user }, 'type'));
    const params = {
      type: 'commentable__comments',
      attributes: {},
      relationships: {
        thread: { data: { id: thread.id, type: thread.type } },
        author: { data: { id: user.id, type: user.type } }
      }
    };

    return super.insert(params, { url: `/v3/discuss/threads/${thread.id}/comments`, cacheMode });
  }
}

export default DiscussService;