Best Python code snippet using localstack_python
eventrouter.js
Source:eventrouter.js  
1/*2 * Copyright 2019-present Open Networking Foundation3 * Licensed under the Apache License, Version 2.0 (the "License");4 * you may not use this file except in compliance with the License.5 * You may obtain a copy of the License at6 * http://www.apache.org/licenses/LICENSE-2.07 * Unless required by applicable law or agreed to in writing, software8 * distributed under the License is distributed on an "AS IS" BASIS,9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.10 * See the License for the specific language governing permissions and11 * limitations under the License.12 */13(function () {14    'use strict';15    const _ = require('lodash');16    const logger = require('../config/logger.js');17    const Client = require('../types/client.js');18    const WorkflowRun = require('../types/workflowrun.js');19    const ws_probe = require('./ws_probe.js');20    const ws_manager = require('./ws_manager.js');21    const ws_workflowrun = require('./ws_workflowrun.js');22    let allClients = {}; // has publishers and subscribers23    let probeClients = {}; // a subset of clients24    let workflowManagerClients = {}; // a subset of clients25    let workflowRunClients = {}; // a subset of clients26    //let io;27    // key: workflow id28    // value: Workflow instance29    let workflows = {};30    // key: workflow run id31    // value: WorkflowRun instance32    let workflowRuns = {};33    let serviceEvents = {34        GREETING: 'cord.workflow.ctlsvc.greeting'35    };36    setInterval(function () {37        let requests = [];38        _.forOwn(workflowRuns, (workflowRun, workflowRunId) => {39            let obj = {40                workflow_id: workflowRun.getWorkflowId(),41                workflow_run_id: workflowRunId42            };43            requests.push(obj);44        });45        checkWorkflowRunStatusBulk(requests);46    }, 5000);47    // add ws_probe events48    _.forOwn(ws_probe.serviceEvents, (wsServiceEvent, key) => {49        serviceEvents[key] = wsServiceEvent;50    });51    // add ws_manager events52    _.forOwn(ws_manager.serviceEvents, (wsServiceEvent, key) => {53        serviceEvents[key] = wsServiceEvent;54    });55    // add ws_workflowrun events56    _.forOwn(ws_workflowrun.serviceEvents, (wsServiceEvent, key) => {57        serviceEvents[key] = wsServiceEvent;58    });59    //const setIO = (ioInstance) => {60    //    io = ioInstance;61    //};62    const checkObject = (obj) => {63        return Object.prototype.toString.call(obj) === '[object Object]';64    };65    const destroy = () => {66        removeClients();67        clearWorkflowRuns();68        clearWorkflows();69    };70    const listWorkflows = () => {71        let workflowList = [];72        _.forOwn(workflows, (_workflow, workflowId) => {73            workflowList.push(workflowId);74        });75        return workflowList;76    };77    const checkWorkflow = (workflowId) => {78        if(workflowId in workflows) {79            return true;80        }81        return false;82    };83    const addWorkflow = (workflow) => {84        if(workflow.getId() in workflows) {85            logger.log('error', `there exists a workflow with the same id - ${workflow.getId()}`);86            return false;87        }88        let workflowId = workflow.getId();89        workflows[workflowId] = workflow;90        return true;91    };92    const getWorkflow = (workflowId) => {93        if(workflowId in workflows) {94            logger.log('warn', `cannot find a workflow with id - ${workflowId}`);95            return null;96        }97        return workflows[workflowId];98    };99    const clearWorkflows = () => {100        _.forOwn(workflows, (_workflow, workflowId) => {101            delete workflows[workflowId];102        });103    };104    const listWorkflowRuns = () => {105        let workflowRunList = [];106        _.forOwn(workflowRuns, (_workflowRun, workflowRunId) => {107            workflowRunList.push(workflowRunId);108        });109        return workflowRunList;110    };111    const checkWorkflowRun = (workflowRunId) => {112        if(workflowRunId in workflowRuns) {113            return true;114        }115        return false;116    };117    const addWorkflowRun = (workflowRun) => {118        let workflowId = workflowRun.getWorkflowId();119        let workflowRunId = workflowRun.getId();120        if(workflowRunId in workflowRuns) {121            logger.log('warn', `there exists a workflow run with the same id - ${workflowRunId}`);122            return false;123        }124        if(!(workflowId in workflows)) {125            logger.log('warn', `cannot find a workflow with id - ${workflowId}`);126            return false;127        }128        workflowRuns[workflowRunId] = workflowRun;129        return true;130    };131    const getWorkflowRun = (workflowRunId) => {132        if(workflowRunId in workflowRuns) {133            logger.log('warn', `cannot find a workflow run with id - ${workflowRunId}`);134            return null;135        }136        return workflowRuns[workflowRunId];137    };138    const clearWorkflowRuns = () => {139        _.forOwn(workflowRuns, (_workflowRun, workflowRunId) => {140            delete workflowRuns[workflowRunId];141        });142    };143    const setWorkflowRunKickstarted = (workflowRunId) => {144        if(!(workflowRunId in workflowRuns)) {145            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);146            return false;147        }148        let workflowRun = workflowRuns[workflowRunId];149        workflowRun.setKickstarted();150        return true;151    };152    const setWorkflowRunStatus = (workflowRunId, status) => {153        if(!(workflowRunId in workflowRuns)) {154            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);155            return false;156        }157        if(status === 'success' || status === 'failed' || status === 'end') {158            removeWorkflowRun(workflowRunId);159        }160        return true;161    };162    const kickstart = (workflowId, workflowRunId) => {163        if(!(workflowId in workflows)) {164            logger.log('warn', `cannot find a workflow with the id - ${workflowId}`);165            return false;166        }167        if(!(workflowRunId in workflowRuns)) {168            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);169            return false;170        }171        ws_manager.kickstartWorkflow(workflowId, workflowRunId);172        return true;173    };174    /*175    const checkWorkflowRunStatus = (workflowId, workflowRunId) => {176        if(!(workflowId in workflows)) {177            logger.log('warn', `cannot find a workflow with the id - ${workflowId}`);178            return false;179        }180        if(!(workflowRunId in workflowRuns)) {181            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);182            return false;183        }184        ws_manager.checkWorkflowRunStatus(workflowId, workflowRunId);185        return true;186    };187    */188    const checkWorkflowRunStatusBulk = (requests) => {189        if(requests) {190            ws_manager.checkWorkflowRunStatusBulk(requests);191            return true;192        }193        return false;194    };195    const removeWorkflow = (workflowId) => {196        if(!(workflowId in workflows)) {197            logger.log('warn', `cannot find a workflow with the id - ${workflowId}`);198            return false;199        }200        // check if there are workflow runs201        for(let key in workflowRuns) {202            if (!workflowRuns.hasOwnProperty(key)) {203                continue;204            }205            let workflowRun = workflowRuns[key];206            if(workflowRun.getWorkflowId() === workflowId) {207                logger.log('warn', `there exists a workflow run for a workflow id - ${workflowId}`);208                return false;209            }210        }211        // we don't use below code becuase it cannot properly stop and return value with 'return'212        // _.forOwn(workflowRuns, (workflowRun, _workflowRunId) => {213        //     if(workflowRun.getWorkflowId() === workflowId) {214        //         logger.log('warn', `there exists a workflow run for a workflow id - ${workflowId}`);215        //         return false;216        //     }217        // });218        delete workflows[workflowId];219        return true;220    };221    const removeWorkflowRun = (workflowRunId) => {222        if(!(workflowRunId in workflowRuns)) {223            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);224            return false;225        }226        let workflowRun = workflowRuns[workflowRunId];227        delete workflowRuns[workflowRunId];228        workflowRun.setFinished();229        return true;230    };231    const emitEvent = (topic, message) => {232        logger.log('debug', `event is raised : topic ${topic}, message ${JSON.stringify(message)}`);233        let runningWorkflows = [];234        // route event to running instances235        _.forOwn(workflowRuns, (workflowRun, workflowRunId) => {236            let workflowId = workflowRun.getWorkflowId();237            let workflow = workflows[workflowId];238            if(workflow.isEventAcceptable(topic)) {239                logger.log('debug', `workflow ${workflowId} accept the event : topic ${topic}`);240                // event is acceped if event has241                // the same key field and its value as workflow_run242                if(workflowRun.isEventAcceptable(topic, message)) {243                    logger.log('debug', `workflow run ${workflowRunId} accept the event : \244                                topic ${topic}, message ${JSON.stringify(message)}`);245                    workflowRun.updateEventKeyFieldValueFromMessage(topic, message);246                    logger.log('debug', `event ${topic} is routed to workflow run ${workflowRunId}`);247                    workflowRun.enqueueEvent(topic, message);248                    // mark to not kickstart a new one249                    runningWorkflows.push(workflowId);250                }251                else {252                    logger.log('debug', `workflow run ${workflowRunId} reject the event : \253                                topic ${topic}, message ${JSON.stringify(message)}`);254                }255            }256        });257        // check if the event is a kickstart event258        _.forOwn(workflows, (workflow, workflowId) => {259            if(!runningWorkflows.includes(workflowId)) {260                if(workflow.isKickstartTopic(topic)) {261                    // we need to buffer the event until workflow run is brought up262                    let workflowRun = WorkflowRun.WorkflowRun.makeNewRun(workflow);263                    workflowRun.updateEventKeyFieldValueFromMessage(topic, message);264                    let workflowRunId = workflowRun.getId();265                    // register for management266                    workflowRuns[workflowRunId] = workflowRun;267                    // route event268                    logger.log('debug', `event ${topic} is routed to a new workflow run ${workflowRunId}`);269                    workflowRun.enqueueEvent(topic, message);270                    // KICKSTART!271                    kickstart(workflowId, workflowRunId);272                }273            }274        });275        return true;276    };277    const countQueuedEvents = (workflowRunId) => {278        // this counts queued events279        if(!(workflowRunId in workflowRuns)) {280            logger.log('warn', `workflow run ${workflowRunId} does not exist`);281            return null;282        }283        let workflowRun = workflowRuns[workflowRunId];284        return workflowRun.lengthEventQueue();285    };286    const fetchEvent = (workflowRunId, taskId, topic) => {287        // this returns an event or an empty obj when there is no message288        if(!(workflowRunId in workflowRuns)) {289            logger.log('warn', `workflow run ${workflowRunId} does not exist`);290            return null;291        }292        let workflowRun = workflowRuns[workflowRunId];293        let workflowId = workflowRun.getWorkflowId();294        if(!(workflowId in workflows)) {295            logger.log('warn', `workflow ${workflowId} does not exist`);296            return null;297        }298        let workflow = workflows[workflowId];299        let task = workflow.getTask(taskId);300        if(!task) {301            logger.log('warn', `workflow ${workflowId} does not have task ${taskId}`);302            return null;303        }304        logger.log('debug', `workflow run ${workflowRunId}, task ${taskId} fetches an event`);305        let event = workflowRun.dequeueEventByTopic(topic);306        if(event) {307            return event;308        }309        else {310            return {};311        }312    };313    const addClient = (c) => {314        let clientId = c.getId();315        let socket = c.getSocket();316        // check id that client is already there317        if(clientId in allClients) {318            logger.log('warn', `there exists a client with the same id - ${clientId}`);319            return false;320        }321        if(c.getType() === Client.Type.PROBE) {322            // probe323            // probe protocol:324            // REQ:325            //      topic: operation326            //      message: {327            //          req_id: <req_id>,328            //          topic: <topic>,329            //          message: <data>330            //      }331            // RES:332            //      topic: topic sent333            //      message: {334            //          req_id: <req_id>,335            //          error: <true/false>,336            //          result: <true/false>,337            //          message: <error message>338            //      }339            allClients[clientId] = c;340            probeClients[clientId] = c;341            // attach probe operations342            let router = ws_probe.getRouter();343            _.forOwn(router, (routerElem, _key) => {344                socket.on(routerElem.topic, (msg) => {345                    logger.log('debug', `received a probe event ${routerElem.topic} - ${JSON.stringify(msg)}`);346                    // handle a common parameter - req_id347                    // when we get req_id, return the same req_id in response.348                    // this is to help identify a request from a response at client-side349                    let req_id = 101010; // default number, signiture350                    if(msg && checkObject(msg)) {351                        if('req_id' in msg) {352                            req_id = msg.req_id;353                        }354                    }355                    routerElem.handler(routerElem.topic, msg || {}, (err, result) => {356                        if(err) {357                            logger.log('warn', `unable to handle a message - ${err}`);358                            socket.emit(routerElem.topic, {359                                req_id: req_id,360                                error: true,361                                result: result,362                                message: err363                            });364                            return;365                        }366                        // we return result367                        if(routerElem.return === undefined || routerElem.return) {368                            socket.emit(routerElem.topic, {369                                req_id: req_id,370                                error: false,371                                result: result372                            });373                        }374                    });375                });376            });377            return true;378        }379        else if(c.getType() === Client.Type.WORKFLOW_MANAGER) {380            // manager381            // manager protocol:382            // REQ:383            //      topic: operation384            //      message: {385            //          req_id: <req_id>,386            //          <data>...387            //      }388            // RES:389            //      topic: topic sent390            //      message: {391            //          req_id: <req_id>,392            //          error: <true/false>,393            //          result: <true/false>,394            //          message: <error message>395            //      }396            allClients[clientId] = c;397            workflowManagerClients[clientId] = c;398            // attach manager operations399            let router = ws_manager.getRouter();400            _.forOwn(router, (routerElem, _key) => {401                socket.on(routerElem.topic, (msg) => {402                    logger.log('debug', `received a manager event ${routerElem.topic} - ${JSON.stringify(msg)}`);403                    // handle a common parameter - req_id404                    // when we get req_id, return the same req_id in response.405                    // this is to help identify a request from a response at client-side406                    let req_id = 101010; // default number, signiture407                    if(msg && checkObject(msg)) {408                        if('req_id' in msg) {409                            req_id = msg.req_id;410                        }411                    }412                    routerElem.handler(routerElem.topic, msg || {}, (err, result) => {413                        if(err) {414                            logger.log('warn', `unable to handle a message - ${err}`);415                            socket.emit(routerElem.topic, {416                                req_id: req_id,417                                error: true,418                                result: result,419                                message: err420                            });421                            return;422                        }423                        // we return result424                        if(routerElem.return === undefined || routerElem.return) {425                            socket.emit(routerElem.topic, {426                                req_id: req_id,427                                error: false,428                                result: result429                            });430                        }431                    });432                });433            });434            return true;435        }436        else if(c.getType() === Client.Type.WORKFLOW_RUN) {437            // workflow run438            // workflow run protocol:439            // REQ:440            //      topic: operation441            //      message: {442            //          req_id: <req_id>,443            //          <data>...444            //      }445            // RES:446            //      topic: topic sent447            //      message: {448            //          req_id: <req_id>,449            //          error: <true/false>,450            //          result: <true/false>,451            //          message: <error message>452            //      }453            // map to WorkflowRun instance454            let workflowId = c.getWorkflowId();455            let workflowRunId = c.getWorkflowRunId();456            let workflowRun;457            if(!(workflowId in workflows)) {458                logger.log('warn', `cannot find a workflow ${workflowId}`);459                return false;460            }461            // register client to workflow run462            if(!(workflowRunId in workflowRuns)) {463                // workflow run not exist yet464                logger.log('warn', `cannot find a workflow run ${workflowRunId}`);465                return false;466            }467            //let workflow = workflows[workflowId];468            allClients[clientId] = c;469            workflowRunClients[clientId] = c;470            // update471            workflowRun = workflowRuns[workflowRunId];472            workflowRun.addClientId(clientId);473            // attach workflow run operations474            let router = ws_workflowrun.getRouter();475            _.forOwn(router, (routerElem, _key) => {476                socket.on(routerElem.topic, (msg) => {477                    logger.log('debug', `received a workflow run event ${routerElem.topic} - ${JSON.stringify(msg)}`);478                    // handle a common parameter - req_id479                    // when we get req_id, return the same req_id in response.480                    // this is to help identify a request from a response at client-side481                    let req_id = 101010; // default number, signiture482                    if(msg && checkObject(msg)) {483                        if('req_id' in msg) {484                            req_id = msg.req_id;485                        }486                    }487                    routerElem.handler(routerElem.topic, msg || {}, (err, result) => {488                        if(err) {489                            logger.log('warn', `unable to handle a message - ${err}`);490                            socket.emit(routerElem.topic, {491                                req_id: req_id,492                                error: true,493                                result: false,494                                message: err495                            });496                            return;497                        }498                        // we return result499                        if(routerElem.return === undefined || routerElem.return) {500                            socket.emit(routerElem.topic, {501                                req_id: req_id,502                                error: false,503                                result: result504                            });505                        }506                    });507                });508            });509            return true;510        }511        return false;512    };513    const removeClient = (id) => {514        if(id in allClients) {515            let removedClient = allClients[id];516            delete allClients[id];517            let type = removedClient.getType();518            if(type === Client.Type.PROBE) {519                delete probeClients[id];520            }521            else if(type === Client.Type.WORKFLOW_MANAGER) {522                delete workflowManagerClients[id];523            }524            else if(type === Client.Type.WORKFLOW_RUN) {525                delete workflowRunClients[id];526                let workflowRunId = removedClient.getWorkflowRunId();527                let workflowRun = workflowRuns[workflowRunId];528                if(workflowRun) {529                    workflowRun.removeClientId(id);530                    //TODO531                    // WorkflowRun can have no clients between tasks532                    // So we should not remove the run until the workflow run finishes533                }534            }535        }536    };537    const removeClients = () => {538        let probeClients = {};539        _.forOwn(probeClients, (_probeClient, clientId) => {540            delete probeClients[clientId];541        });542        _.forOwn(workflowManagerClients, (_workflowManagerClient, clientId) => {543            delete workflowManagerClients[clientId];544        });545        _.forOwn(workflowRunClients, (_workflowRunClients, clientId) => {546            delete workflowRunClients[clientId];547        });548        _.forOwn(allClients, (client, clientId) => {549            client.getSocket().disconnect(true);550            delete allClients[clientId];551        });552    }553    module.exports = {554        serviceEvents: serviceEvents,555        destroy: destroy,556        getClients: () => { return allClients; },557        getProbeClients: () => { return probeClients; },558        getWorkflowManagerClients: () => { return workflowManagerClients; },559        getWorkflowRunClients: () => { return workflowRunClients; },560        clientType: Client.Type,561        //setIO: setIO,562        emitEvent: emitEvent,563        countQueuedEvents: countQueuedEvents,564        fetchEvent: fetchEvent,565        addClient: addClient,566        removeClient: removeClient,567        removeClients: removeClients,568        addWorkflow: addWorkflow,569        getWorkflow: getWorkflow,570        listWorkflows: listWorkflows,571        checkWorkflow: checkWorkflow,572        removeWorkflow: removeWorkflow,573        clearWorkflows: clearWorkflows,574        addWorkflowRun: addWorkflowRun,575        getWorkflowRun: getWorkflowRun,576        listWorkflowRuns: listWorkflowRuns,577        checkWorkflowRun: checkWorkflowRun,578        removeWorkflowRun: removeWorkflowRun,579        clearWorkflowRuns: clearWorkflowRuns,580        setWorkflowRunKickstarted: setWorkflowRunKickstarted,581        setWorkflowRunStatus: setWorkflowRunStatus582    };...hook.js
Source:hook.js  
...23}24/**25 * Call every function in the array `hook' with the remaining26 * arguments of this function.  Note: This should only be used by27 * define_hook and friends to define hook.run(...) functions.  Hooks28 * should always be run by calling hook.run(...).29 */30function run_hooks (hook, args) {31    if (hook == null)32        return;33    for (let i = 0, hlen = hook.length; i < hlen; ++i)34        hook[i].apply(null, Array.prototype.slice.call(args));35}36function run_hooks_until_success (hook, args) {37    if (hook == null)38        return false;39    var result;40    for (let i = 0, hlen = hook.length; i < hlen; ++i)41        if ((result = hook[i].apply(null, Array.prototype.slice.call(args))))42            return result;...course_card_model.js
Source:course_card_model.js  
1/* globals gettext */2import Backbone from 'backbone';3import DateUtils from 'edx-ui-toolkit/js/utils/date-utils';4import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';5/**6 * Model for Course Programs.7 */8class CourseCardModel extends Backbone.Model {9  initialize(data) {10    if (data) {11      this.context = data;12      this.setActiveCourseRun(this.getCourseRun(data), data.user_preferences);13    }14  }15  getCourseRun(course) {16    const enrolledCourseRun = course.course_runs.find(run => run.is_enrolled);17    const openEnrollmentCourseRuns = this.getEnrollableCourseRuns();18    let desiredCourseRun;19    // If the learner has an existing, unexpired enrollment,20    // use it to populate the model.21    if (enrolledCourseRun && !course.expired) {22      desiredCourseRun = enrolledCourseRun;23    } else if (openEnrollmentCourseRuns.length > 0) {24      if (openEnrollmentCourseRuns.length === 1) {25        desiredCourseRun = openEnrollmentCourseRuns[0];26      } else {27        desiredCourseRun = CourseCardModel.getUnselectedCourseRun(openEnrollmentCourseRuns);28      }29    } else {30      desiredCourseRun = CourseCardModel.getUnselectedCourseRun(course.course_runs);31    }32    return desiredCourseRun;33  }34  getCourseRunWithHighestGrade(grades) {35    const allEnrolledCourseRuns = this.context.course_runs.filter(run => run.is_enrolled);36    if (allEnrolledCourseRuns.length <= 1) {37      return null;38    }39    allEnrolledCourseRuns.sort((a, b) => (grades[a.key] || 0) - (grades[b.key] || 0));40    return allEnrolledCourseRuns[allEnrolledCourseRuns.length - 1];41  }42  updateCourseRunWithHighestGrade(grades) {43    const courseRunWithHighestGrade = this.getCourseRunWithHighestGrade(grades);44    if (courseRunWithHighestGrade) {45      this.setActiveCourseRun(courseRunWithHighestGrade, this.context.user_preferences);46    }47  }48  isEnrolledInSession() {49    // Returns true if the user is currently enrolled in a session of the course50    return this.context.course_runs.find(run => run.is_enrolled) !== undefined;51  }52  static getUnselectedCourseRun(courseRuns) {53    const unselectedRun = {};54    if (courseRuns && courseRuns.length > 0) {55      const courseRun = courseRuns[0];56      $.extend(unselectedRun, {57        marketing_url: courseRun.marketing_url,58        is_enrollment_open: courseRun.is_enrollment_open,59        key: courseRun.key || '',60        is_mobile_only: courseRun.is_mobile_only || false,61      });62    }63    return unselectedRun;64  }65  getEnrollableCourseRuns() {66    const rawCourseRuns = this.context.course_runs.filter(run => (67      run.is_enrollment_open &&68      !run.is_enrolled &&69      !run.is_course_ended &&70      run.status === 'published'71    ));72    // Deep copy to avoid mutating this.context.73    const enrollableCourseRuns = $.extend(true, [], rawCourseRuns);74    // These are raw course runs from the server. The start75    // dates are ISO-8601 formatted strings that need to be76    // prepped for display.77    enrollableCourseRuns.forEach((courseRun) => {78      Object.assign(courseRun, {79        start_date: CourseCardModel.formatDate(courseRun.start),80        end_date: CourseCardModel.formatDate(courseRun.end),81        // This is used to render the date when selecting a course run to enroll in82        dateString: this.formatDateString(courseRun),83      });84    });85    return enrollableCourseRuns;86  }87  getUpcomingCourseRuns() {88    return this.context.course_runs.filter(run => (89      !run.is_enrollment_open &&90      !run.is_enrolled &&91      !run.is_course_ended &&92      run.status === 'published'93    ));94  }95  static formatDate(date, userPreferences) {96    let userTimezone = '';97    let userLanguage = '';98    if (userPreferences !== undefined) {99      userTimezone = userPreferences.time_zone;100      userLanguage = userPreferences['pref-lang'];101    }102    const context = {103      datetime: date,104      timezone: userTimezone,105      language: userLanguage,106      format: DateUtils.dateFormatEnum.shortDate,107    };108    return DateUtils.localize(context);109  }110  static getCertificatePriceString(run) {111    if ('seats' in run && run.seats.length) {112      // eslint-disable-next-line consistent-return113      const upgradeableSeats = run.seats.filter((seat) => {114        const upgradeableSeatTypes = ['verified', 'professional', 'no-id-professional', 'credit'];115        return upgradeableSeatTypes.indexOf(seat.type) >= 0;116      });117      if (upgradeableSeats.length > 0) {118        const upgradeableSeat = upgradeableSeats[0];119        if (upgradeableSeat) {120          const currency = upgradeableSeat.currency;121          if (currency === 'USD') {122            return `$${upgradeableSeat.price}`;123          }124          return `${upgradeableSeat.price} ${currency}`;125        }126      }127    }128    return null;129  }130  formatDateString(run) {131    const pacingType = run.pacing_type;132    let dateString;133    const start = CourseCardModel.valueIsDefined(run.start_date) ?134      run.advertised_start || run.start_date :135      this.get('start_date');136    const end = CourseCardModel.valueIsDefined(run.end_date) ? run.end_date : this.get('end_date');137    const now = new Date();138    const startDate = new Date(start);139    const endDate = new Date(end);140    if (pacingType === 'self_paced') {141      if (start) {142        dateString = startDate > now ?143          StringUtils.interpolate(gettext('(Self-paced) Starts {start}'), { start }) :144          StringUtils.interpolate(gettext('(Self-paced) Started {start}'), { start });145      } else if (end && endDate > now) {146        dateString = StringUtils.interpolate(gettext('(Self-paced) Ends {end}'), { end });147      } else if (end && endDate < now) {148        dateString = StringUtils.interpolate(gettext('(Self-paced) Ended {end}'), { end });149      }150    } else if (start && end) {151      dateString = `${start} - ${end}`;152    } else if (start) {153      dateString = startDate > now ?154                                StringUtils.interpolate(gettext('Starts {start}'), { start }) :155                                StringUtils.interpolate(gettext('Started {start}'), { start });156    } else if (end) {157      dateString = StringUtils.interpolate(gettext('Ends {end}'), { end });158    }159    return dateString;160  }161  static valueIsDefined(val) {162    return !([undefined, 'None', null].indexOf(val) >= 0);163  }164  setActiveCourseRun(courseRun, userPreferences) {165    let startDateString;166    let courseTitleLink = '';167    const isEnrolled = this.isEnrolledInSession() && courseRun.key;168    if (courseRun) {169      if (CourseCardModel.valueIsDefined(courseRun.advertised_start)) {170        startDateString = courseRun.advertised_start;171      } else {172        startDateString = CourseCardModel.formatDate(courseRun.start, userPreferences);173      }174      if (isEnrolled && courseRun.course_url) {175        courseTitleLink = courseRun.course_url;176      } else if (!isEnrolled && courseRun.marketing_url) {177        courseTitleLink = CourseCardModel.updateMarketingUrl(courseRun);178      }179      this.set({180        certificate_url: courseRun.certificate_url,181        course_run_key: courseRun.key || '',182        course_url: courseRun.course_url || '',183        title: this.context.title,184        end_date: CourseCardModel.formatDate(courseRun.end, userPreferences),185        enrollable_course_runs: this.getEnrollableCourseRuns(),186        is_course_ended: courseRun.is_course_ended,187        is_enrolled: isEnrolled,188        is_enrollment_open: courseRun.is_enrollment_open,189        course_key: this.context.key,190        user_entitlement: this.context.user_entitlement,191        is_unfulfilled_entitlement: this.context.user_entitlement && !isEnrolled,192        marketing_url: courseRun.marketing_url,193        mode_slug: courseRun.type,194        start_date: startDateString,195        upcoming_course_runs: this.getUpcomingCourseRuns(),196        upgrade_url: courseRun.upgrade_url,197        price: CourseCardModel.getCertificatePriceString(courseRun),198        course_title_link: courseTitleLink,199        is_mobile_only: courseRun.is_mobile_only || false,200      });201      // This is used to render the date for completed and in progress courses202      this.set({ dateString: this.formatDateString(courseRun) });203    }204  }205  setUnselected() {206    // Called to reset the model back to the unselected state.207    const unselectedCourseRun = CourseCardModel.getUnselectedCourseRun(this.get('enrollable_course_runs'));208    this.setActiveCourseRun(unselectedCourseRun);209  }210  updateCourseRun(courseRunKey) {211    const selectedCourseRun = this.get('course_runs').find(run => run.key === courseRunKey);212    if (selectedCourseRun) {213      // Update the current context to set the course run to the enrolled state214      this.context.course_runs.forEach((run) => {215        Object.assign(run, {216          is_enrolled: run.is_enrolled || run.key === selectedCourseRun.key,217        });218      });219      this.setActiveCourseRun(selectedCourseRun);220    }221  }222  // update marketing url for deep linking if is_mobile_only true223  static updateMarketingUrl(courseRun) {224    if (courseRun.is_mobile_only === true) {225      const marketingUrl = courseRun.marketing_url;226      let href = marketingUrl;227      if (marketingUrl.indexOf('course_info?path_id') < 0) {228        const start = marketingUrl.indexOf('course/');229        let path;230        if (start > -1) {231          path = marketingUrl.substr(start);232        }233        href = `edxapp://course_info?path_id=${path}`;234      }235      return href;236    }237    return courseRun.marketing_url;238  }239}...course_card_model.cfeeb788acc3.js
Source:course_card_model.cfeeb788acc3.js  
1/* globals gettext */2import Backbone from 'backbone';3import DateUtils from 'edx-ui-toolkit/js/utils/date-utils';4import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';5/**6 * Model for Course Programs.7 */8class CourseCardModel extends Backbone.Model {9  initialize(data) {10    if (data) {11      this.context = data;12      this.setActiveCourseRun(this.getCourseRun(data), data.user_preferences);13    }14  }15  getCourseRun(course) {16    const enrolledCourseRun = course.course_runs.find(run => run.is_enrolled);17    const openEnrollmentCourseRuns = this.getEnrollableCourseRuns();18    let desiredCourseRun;19    // If the learner has an existing, unexpired enrollment,20    // use it to populate the model.21    if (enrolledCourseRun && !course.expired) {22      desiredCourseRun = enrolledCourseRun;23    } else if (openEnrollmentCourseRuns.length > 0) {24      if (openEnrollmentCourseRuns.length === 1) {25        desiredCourseRun = openEnrollmentCourseRuns[0];26      } else {27        desiredCourseRun = CourseCardModel.getUnselectedCourseRun(openEnrollmentCourseRuns);28      }29    } else {30      desiredCourseRun = CourseCardModel.getUnselectedCourseRun(course.course_runs);31    }32    return desiredCourseRun;33  }34  getCourseRunWithHighestGrade(grades) {35    const allEnrolledCourseRuns = this.context.course_runs.filter(run => run.is_enrolled);36    if (allEnrolledCourseRuns.length <= 1) {37      return null;38    }39    allEnrolledCourseRuns.sort((a, b) => (grades[a.key] || 0) - (grades[b.key] || 0));40    return allEnrolledCourseRuns[allEnrolledCourseRuns.length - 1];41  }42  updateCourseRunWithHighestGrade(grades) {43    const courseRunWithHighestGrade = this.getCourseRunWithHighestGrade(grades);44    if (courseRunWithHighestGrade) {45      this.setActiveCourseRun(courseRunWithHighestGrade, this.context.user_preferences);46    }47  }48  isEnrolledInSession() {49    // Returns true if the user is currently enrolled in a session of the course50    return this.context.course_runs.find(run => run.is_enrolled) !== undefined;51  }52  static getUnselectedCourseRun(courseRuns) {53    const unselectedRun = {};54    if (courseRuns && courseRuns.length > 0) {55      const courseRun = courseRuns[0];56      $.extend(unselectedRun, {57        marketing_url: courseRun.marketing_url,58        is_enrollment_open: courseRun.is_enrollment_open,59        key: courseRun.key || '',60        is_mobile_only: courseRun.is_mobile_only || false,61      });62    }63    return unselectedRun;64  }65  getEnrollableCourseRuns() {66    const rawCourseRuns = this.context.course_runs.filter(run => (67      run.is_enrollment_open &&68      !run.is_enrolled &&69      !run.is_course_ended &&70      run.status === 'published'71    ));72    // Deep copy to avoid mutating this.context.73    const enrollableCourseRuns = $.extend(true, [], rawCourseRuns);74    // These are raw course runs from the server. The start75    // dates are ISO-8601 formatted strings that need to be76    // prepped for display.77    enrollableCourseRuns.forEach((courseRun) => {78      Object.assign(courseRun, {79        start_date: CourseCardModel.formatDate(courseRun.start),80        end_date: CourseCardModel.formatDate(courseRun.end),81        // This is used to render the date when selecting a course run to enroll in82        dateString: this.formatDateString(courseRun),83      });84    });85    return enrollableCourseRuns;86  }87  getUpcomingCourseRuns() {88    return this.context.course_runs.filter(run => (89      !run.is_enrollment_open &&90      !run.is_enrolled &&91      !run.is_course_ended &&92      run.status === 'published'93    ));94  }95  static formatDate(date, userPreferences) {96    let userTimezone = '';97    let userLanguage = '';98    if (userPreferences !== undefined) {99      userTimezone = userPreferences.time_zone;100      userLanguage = userPreferences['pref-lang'];101    }102    const context = {103      datetime: date,104      timezone: userTimezone,105      language: userLanguage,106      format: DateUtils.dateFormatEnum.shortDate,107    };108    return DateUtils.localize(context);109  }110  static getCertificatePriceString(run) {111    if ('seats' in run && run.seats.length) {112      // eslint-disable-next-line consistent-return113      const upgradeableSeats = run.seats.filter((seat) => {114        const upgradeableSeatTypes = ['verified', 'professional', 'no-id-professional', 'credit'];115        return upgradeableSeatTypes.indexOf(seat.type) >= 0;116      });117      if (upgradeableSeats.length > 0) {118        const upgradeableSeat = upgradeableSeats[0];119        if (upgradeableSeat) {120          const currency = upgradeableSeat.currency;121          if (currency === 'USD') {122            return `$${upgradeableSeat.price}`;123          }124          return `${upgradeableSeat.price} ${currency}`;125        }126      }127    }128    return null;129  }130  formatDateString(run) {131    const pacingType = run.pacing_type;132    let dateString;133    const start = CourseCardModel.valueIsDefined(run.start_date) ?134      run.advertised_start || run.start_date :135      this.get('start_date');136    const end = CourseCardModel.valueIsDefined(run.end_date) ? run.end_date : this.get('end_date');137    const now = new Date();138    const startDate = new Date(start);139    const endDate = new Date(end);140    if (pacingType === 'self_paced') {141      if (start) {142        dateString = startDate > now ?143          StringUtils.interpolate(gettext('(Self-paced) Starts {start}'), { start }) :144          StringUtils.interpolate(gettext('(Self-paced) Started {start}'), { start });145      } else if (end && endDate > now) {146        dateString = StringUtils.interpolate(gettext('(Self-paced) Ends {end}'), { end });147      } else if (end && endDate < now) {148        dateString = StringUtils.interpolate(gettext('(Self-paced) Ended {end}'), { end });149      }150    } else if (start && end) {151      dateString = `${start} - ${end}`;152    } else if (start) {153      dateString = startDate > now ?154                                StringUtils.interpolate(gettext('Starts {start}'), { start }) :155                                StringUtils.interpolate(gettext('Started {start}'), { start });156    } else if (end) {157      dateString = StringUtils.interpolate(gettext('Ends {end}'), { end });158    }159    return dateString;160  }161  static valueIsDefined(val) {162    return !([undefined, 'None', null].indexOf(val) >= 0);163  }164  setActiveCourseRun(courseRun, userPreferences) {165    let startDateString;166    let courseTitleLink = '';167    const isEnrolled = this.isEnrolledInSession() && courseRun.key;168    if (courseRun) {169      if (CourseCardModel.valueIsDefined(courseRun.advertised_start)) {170        startDateString = courseRun.advertised_start;171      } else {172        startDateString = CourseCardModel.formatDate(courseRun.start, userPreferences);173      }174      if (isEnrolled && courseRun.course_url) {175        courseTitleLink = courseRun.course_url;176      } else if (!isEnrolled && courseRun.marketing_url) {177        courseTitleLink = CourseCardModel.updateMarketingUrl(courseRun);178      }179      this.set({180        certificate_url: courseRun.certificate_url,181        course_run_key: courseRun.key || '',182        course_url: courseRun.course_url || '',183        title: this.context.title,184        end_date: CourseCardModel.formatDate(courseRun.end, userPreferences),185        enrollable_course_runs: this.getEnrollableCourseRuns(),186        is_course_ended: courseRun.is_course_ended,187        is_enrolled: isEnrolled,188        is_enrollment_open: courseRun.is_enrollment_open,189        course_key: this.context.key,190        user_entitlement: this.context.user_entitlement,191        is_unfulfilled_entitlement: this.context.user_entitlement && !isEnrolled,192        marketing_url: courseRun.marketing_url,193        mode_slug: courseRun.type,194        start_date: startDateString,195        upcoming_course_runs: this.getUpcomingCourseRuns(),196        upgrade_url: courseRun.upgrade_url,197        price: CourseCardModel.getCertificatePriceString(courseRun),198        course_title_link: courseTitleLink,199        is_mobile_only: courseRun.is_mobile_only || false,200      });201      // This is used to render the date for completed and in progress courses202      this.set({ dateString: this.formatDateString(courseRun) });203    }204  }205  setUnselected() {206    // Called to reset the model back to the unselected state.207    const unselectedCourseRun = CourseCardModel.getUnselectedCourseRun(this.get('enrollable_course_runs'));208    this.setActiveCourseRun(unselectedCourseRun);209  }210  updateCourseRun(courseRunKey) {211    const selectedCourseRun = this.get('course_runs').find(run => run.key === courseRunKey);212    if (selectedCourseRun) {213      // Update the current context to set the course run to the enrolled state214      this.context.course_runs.forEach((run) => {215        Object.assign(run, {216          is_enrolled: run.is_enrolled || run.key === selectedCourseRun.key,217        });218      });219      this.setActiveCourseRun(selectedCourseRun);220    }221  }222  // update marketing url for deep linking if is_mobile_only true223  static updateMarketingUrl(courseRun) {224    if (courseRun.is_mobile_only === true) {225      const marketingUrl = courseRun.marketing_url;226      let href = marketingUrl;227      if (marketingUrl.indexOf('course_info?path_id') < 0) {228        const start = marketingUrl.indexOf('course/');229        let path;230        if (start > -1) {231          path = marketingUrl.substr(start);232        }233        href = `edxapp://course_info?path_id=${path}`;234      }235      return href;236    }237    return courseRun.marketing_url;238  }239}...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
