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!!