Manual Reference Source Test

src/helpers/content/Content.js

import ContentType from './ContentType';
import ContentModel from '../../models/content/Content';
import ContentService from '../../services/ContentService';
import StatusService from '../../services/StatusService';
import Commentable from '../../utilities/mixins/Commentable';
import Helper from '../Helper';
// import Storage from '../Storage';
import { aggregate } from '../../utilities/ClassUtility';
import { validate, hasToken, isRequired } from '../../utilities/ValidationUtility';
import { clinical6 } from '../..';

/**
 * Helper class representing Content.
 */
class Content extends aggregate(ContentModel, Helper, Commentable) {
  /**
   * Creates an instance of Content.
   *
   * @param {String|ContentType}  contentType         - Content Type string
   * @param {Object}              json                - The data of the object for ContentModel
   * @param {?Number}             json.id             - The ID of the content
   * @param {?String}             json.title          - Title of the content
   * @param {?String}             json.description    - A description related to the content
   * @param {?String}             json.created_at     - The time at which the content was created
   * @param {?String}             json.updated_at     - The time at which the content was updated
   * @param {?Number}             json.position       - The platform position content is put
   * @param {?Array}              json.tags           - The tags to describe the content
   * @param {?Object}             json.brand          - The brand to describe the content
   * @param {?Object}             [options={}]        - Options available to support the API.
   * @param {?String}             options.version     - Version defaults to 'v2'
   * @param {?String}             options.owner_type  - Owner Type defaults to 'mobile_user'
   * @param {?Object}             [meta={}]           - Meta data supporting this item
   */
  constructor(contentType = undefined, json = {}, options = {}, meta = {}) {
    let _json;
    if (typeof contentType === 'string'
      || (typeof contentType === 'object' && contentType.type === 'dynamic_content__content_types')
      || !contentType) {
      super(json);
      this.contentType = contentType;
      _json = json;
    } else {
      super(contentType);
      _json = contentType;
    }
    // console.log(_json);
    /** @type {Object} */
    this._options = { version: 'v2' };

    // copy over data
    this.options = options;
    this._data = _json;
    /** @type {Object} */
    this._meta = meta;
    this.deserializeRelationshipStubs(_json);
    this.syncRelationships(_json);
  }

  /**
   * Set the attribute of the current content
   *
   * @param {String} key - A String indicating the attribute key
   * @param {(String|Number)} value - Needs to be a String or Number
   *
   * @example
   * myContent.set('title', 'The Tale of Two Cities');
   */
  set(key, value) {
    /** @type {Any} */
    this[key] = value;
  }

  /**
   * Get the value of an attribute of the current content
   *
   * @param {String} key - A String indicating the attribute key
   * @return {(String|Number)} - The value of the attribute
   *
   * @example
   * myContent.get('title');
   */
  get(key) {
    return this[key];
  }

  /**
   * Set _data to set information to the current object.
   *
   * @param {Object} data - A json object
   */
  set _data(data) {
    Object.assign(this, new ContentModel(data));
  }

  /**
   * Get _data to quickly get the raw data without options.
   */
  get _data() {
    const clone = JSON.parse(JSON.stringify(this));
    delete clone._options;
    delete clone._meta;
    return clone;
  }

  /**
   * Get objectType
   * @return {String} - Object Type
   */
  get objectType() { return 'dynamic_content/content'; }

  /**
   * Set the options used for API calls
   * - owner (unique identifier / id)
   * - ownerType (content type)
   * - version
   *
   * @param {Object} options - A json object with options
   */

  /** @type {Object} */
  get options() {
    return this._options;
  }

  /**
   * Set the options used for API calls
   * - owner (unique identifier / id)
   * - ownerType (content type)
   * - version
   *
   * @type {Object}
   * @param {Object} options - A json object with options
   */
  set options(options) {
    Object.assign(this._options, options);
  }

  /** @type {String} */
  get ownerType() { return this._options.owner_type; }

  /** @type {String} */
  set ownerType(ownerType) { this._options.owner_type = ownerType; }

  /** @type {User} */
  get owner() {
    return this._owner;
  }

  /** @type {User} */
  set owner(owner) {
    /** @type {User} */
    this._owner = owner;
  }

  /**
   * Get resource
   * @return {String} - resource - this.content_type
   */
  get resource() {
    return this.content_type;
  }

  /**
   * Get status
   * @return {String} - Status
   */
  get status() {
    return this._status;
  }

  /** @type {String} */
  set status(status) {
    /** @type {String} */
    this._status = status;
  }

  /** @type {User} */
  get mobileUser() {
    return this._mobile_user;
  }

  /** @type {User} */
  set mobileUser(mobileUser) {
    /** @type {User} */
    this._mobile_user = mobileUser;
  }

  /** @type {ContentType} */
  get contentType() {
    return this._relationships.content_type;
  }

  /** @type {ContentType} */
  set contentType(contentType) {
    if (!this._relationships) {
      this._relationships = {};
    }
    if (typeof contentType === 'string') {
      /** @type {ContentType} */
      this._relationships.content_type = new ContentType({ permanent_link: contentType });
      // this.syncRelationships();
    } else {
      this._relationships.content_type = contentType;
    }
  }

  /** @type {String}  - The type */
  static get type() {
    return 'dynamic_content__contents';
  }

  /**
   * Synchronize the relationships from storage to the current object
   *
   * @return {Promise}
   */
  async syncRelationships(json) {
    await super.syncRelationships(json);
    if (this.contentType && this.contentType.permanentLink && !this.contentType.id) {
      // Handle Content Type by Permlink (not id);
      const types = await clinical6.get(ContentType);
      if (types && types.find) {
        this.contentType = types.find(c => (this.contentType.permanentLink === c.permanentLink));
      }
      // TODO insert content type when it doesn't exist
      // else {
      //   this.contentType = await this.contentType.save();
      // }
    }
  }

  // syncRelationships() {
  //   const storage = new Storage();
  //   const permanentLink = this.contentType.permanentLink;
  //   const self = this;

  //   return super.syncRelationships().then(() => new Promise((resolve) => {
  //     if (!self.contentType.id) {
  //       // Handle Content Type by Permlink (not id);
  //       storage.contentTypes.then((typesMap) => {
  //         const typesArray = Object.values(typesMap);
  //         self.contentType = typesArray.find(c => (permanentLink === c.permanentLink));
  //         resolve(self);
  //       });
  //     } else {
  //       resolve(self);
  //     }
  //   }));
  // }

  /**
   * Deletes a content
   * @return {Promise} - Returns a promise via ajax call.
   *
   * @example
   * import { Content, Client } from 'clinical6';
   *
   * // Removes content from server and local storage
   * const content = new Content({...});
   * content.delete();
   *
   * // No longer in storage
   * Client.instance.storageUtility.has('contents', { id: 1 });
   */
  delete() {
    const service = new ContentService();
    return service.delete(this);
  }

  /**
   * Get Status and set it to this._status
   *
   * @return {Promise<any>} - A Promise containing the status (String)
   *
   * @example
   * myContent.getStatus((status) => {
   *   console.log('status', status);
   *   console.log('status', myContent.status);
   * });
   */
  getStatus() {
    validate('Content getStatus()',
      hasToken(),
      isRequired({
        content_type: this.content_type,
        name: this.tags[0].name,
        ownerType: this.ownerType,
        owner: this.owner,
      }));

    const objectType = this.content_type;
    const object = this.tags[0].name;

    return (new StatusService()).getStatus(objectType, object, this.ownerType, this.owner)
      .then(data => (this._status = data.status.value));
  }

  /**
   * Saves the current instance of Content
   *
   * @return {Object} - Returns a promise via ajax call.
   *
   * @example
   * let car = new client.Content();
   * car.set('content_type', 'car');
   * car.set('title', 'My Car');
   * car.set('make', 'Toyota')
   * car.set('model', 'Corolla')
   * car.set('year', 2006)
   * // inserts
   * car.save().then(() => {
   *   // car now has id
   *   car.set('year', 2007);
   *   return car.save(); // car had id so this last save is an update
   * });
   */
  save() {
    return (this.id) ? (new ContentService()).update(this) : (new ContentService()).insert(this);
  }
}

export default Content;