Best Python code snippet using playwright-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}...LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
