How to use errorMessage method in stryker-parent

Best JavaScript code snippet using stryker-parent

user-controller.js

Source:user-controller.js Github

copy

Full Screen

1const Path = require(`path`);2const User = require('../models').users;3const UniqueConstraintError = require('sequelize').UniqueConstraintError;4const {5 hashPassword,6 comparePassword,7 validatePassword,8 validateEmail,9 generateUserToken10} = require('../helpers/validation-helper.js');11const {12 errorMessage,13 successMessage,14 status15} = require('../helpers/response-helper.js');16// Don`t use in production! Only for testing APIs functionality17exports.createAdminFather = async (req, res) => {18 const hashedPassword = hashPassword('superpass');19 const adminFather = {20 email: 'admin-father@gmail.com',21 password: hashedPassword,22 first_name: 'Father',23 last_name: 'Admins',24 is_admin: true25 };26 try {27 const data = await User.create(adminFather);28 const token = generateUserToken(data.email, data.id, data.is_admin, data.first_name, data.last_name);29 successMessage.data = {30 id: data.id,31 email: data.email,32 firstname: data.first_name,33 lastname: data.last_name,34 token: token35 };36 return res.status(status.created).send(successMessage);37 } catch (error) {38 if (error instanceof UniqueConstraintError) {39 errorMessage.error = 'Admin Father already exist';40 return res.status(status.conflict).send(errorMessage);41 }42 errorMessage.error = `Operation was not successful ${error}`;43 return res.status(status.error).send(errorMessage);44 }45};46// Don`t use in production! Only for testing APIs functionality47exports.signInAdminFather = async (req, res) => {48 const adminFatherEmail = 'admin-father@gmail.com';49 try {50 const data = await User.findOne({51 where: {52 email: adminFatherEmail53 }54 });55 if (data === null) {56 errorMessage.error = `Admin Father do not exists`;57 return res.status(status.notfound).send(errorMessage);58 }59 const token = generateUserToken(data.email, data.id, data.is_admin, data.first_name, data.last_name);60 successMessage.data = {61 id: data.id,62 email: data.email,63 firstname: data.first_name,64 lastname: data.last_name,65 token: token66 };67 return res.status(status.success).send(successMessage);68 } catch (error) {69 errorMessage.error = `Operation was not successful ${error}`;70 return res.status(status.error).send(errorMessage);71 }72};73exports.createUser = async (req, res) => {74 const email = req.body.email.toLowerCase(),75 password = req.body.password;76 if (!validateEmail(email)) {77 errorMessage.error = 'Please enter a valid Email';78 return res.status(status.bad).send(errorMessage);79 }80 if (!validatePassword(password)) {81 errorMessage.error = 'Password must be more than 4 characters';82 return res.status(status.bad).send(errorMessage);83 }84 const hashedPassword = hashPassword(password);85 const user = {86 email: email,87 password: hashedPassword,88 first_name: req.body.firstname,89 last_name: req.body.lastname,90 };91 try {92 const data = await User.create(user);93 const token = generateUserToken(data.email, data.id, data.is_admin, data.first_name, data.last_name);94 successMessage.data = {95 id: data.id,96 email: data.email,97 firstname: data.first_name,98 lasrname: data.last_name,99 token: token100 };101 return res.status(status.created).send(successMessage);102 } catch (error) {103 if (error instanceof UniqueConstraintError) {104 errorMessage.error = `User with email: ${email} already exist`;105 return res.status(status.conflict).send(errorMessage);106 }107 errorMessage.error = `Operation was not successful ${error}`;108 return res.status(status.error).send(errorMessage);109 }110};111exports.signInUser = async (req, res) => {112 const email = req.body.email.toLowerCase(),113 password = req.body.password;114 if (!validateEmail(email) || !validatePassword(password)) {115 errorMessage.error = 'Please enter a valid Email or Password';116 return res.status(status.bad).send(errorMessage);117 }118 try {119 const user = await User.findOne({120 where: {121 email: email122 }123 });124 if (user === null) {125 errorMessage.error = `User with email: ${email} do not exists`;126 return res.status(status.notfound).send(errorMessage);127 }128 if (!comparePassword(user.password, password)) {129 errorMessage.error = 'Incorrect Password';130 return res.status(status.bad).send(errorMessage);131 }132 const token = generateUserToken(user.email, user.id, user.is_admin, user.first_name, user.last_name);133 successMessage.data = {134 id: user.id,135 email: user.email,136 firstname: user.first_name,137 lasrname: user.last_name,138 token: token139 };140 return res.status(status.success).send(successMessage);141 } catch (error) {142 errorMessage.error = `Operation was not successful ${error}`;143 return res.status(status.error).send(errorMessage);144 }145};146exports.retrieveUser = async (req, res) => {147 const retrievedUserId = Path.basename(req.params.id);148 if (req.user.id != retrievedUserId && !req.user.admin) {149 errorMessage.error = 'You can`t retrive this User';150 return res.status(status.unauthorized).send(errorMessage);151 }152 try {153 const data = await User.findOne({154 where: {155 id: retrievedUserId156 }157 });158 if (data === null) {159 errorMessage.error = `User with id: ${retrievedUserId} do not exists`;160 return res.status(status.notfound).send(errorMessage);161 }162 successMessage.data = {163 id: data.id,164 email: data.email,165 firstname: data.first_name,166 lastname: data.last_name,167 admin: data.is_admin168 }169 return res.status(status.success).send(successMessage);170 } catch (error) {171 errorMessage.error = `Operation was not successful ${error}`;172 return res.status(status.error).send(errorMessage);173 }174};175exports.editUser = async (req, res) => {176 const editedUserId = Path.basename(req.params.id);177 if (!req.body.email && !req.body.newpassword && !req.body.firstname && !req.body.lastname && !req.body.admin) {178 errorMessage.error = 'The request has no properties allowed to change';179 return res.status(status.bad).send(errorMessage);180 }181 if (req.body.email || req.body.newpassword || req.body.firstname || req.body.lastname) {182 if (req.user.id != editedUserId) {183 errorMessage.error = 'You can`t edit this properties';184 return res.status(status.unauthorized).send(errorMessage);185 }186 }187 if (req.body.admin === true && !req.user.admin) {188 errorMessage.error = 'Only Admins may update other users to Admin';189 return res.status(status.unauthorized).send(errorMessage);190 }191 try {192 const data = await User.findOne({193 where: {194 id: editedUserId195 }196 });197 if (data === null) {198 errorMessage.error = `User with id: ${editedUserId} do not exists`;199 return res.status(status.notfound).send(errorMessage);200 }201 if (req.body.email) {202 const newEmail = req.body.email.toLowerCase();203 const similarEmailUser = await User.findOne({204 where: {205 email: newEmail206 }207 });208 if (similarEmailUser !== null) {209 errorMessage.error = `User with email: ${newEmail} already exist`;210 return res.status(status.conflict).send(errorMessage);211 }212 data.email = newEmail;213 }214 if (req.body.newpassword) {215 const oldPassword = req.body.password;216 const newPassword = req.body.newpassword;217 if (!comparePassword(data.password, oldPassword)) {218 errorMessage.error = `Incorrect old Password`;219 return res.status(status.bad).send(errorMessage);220 }221 if (!validatePassword(newPassword)) {222 errorMessage.error = 'Invalid new password. The password must be more than 4 characters.';223 return res.status(status.bad).send(errorMessage);224 }225 data.password = hashPassword(newPassword);226 }227 if (req.body.firstname) {228 data.first_name = req.body.firstname;229 }230 if (req.body.lastname) {231 data.last_name = req.body.lastname;232 }233 if (req.body.admin === true) {234 data.is_admin = true;235 }236 await data.save();237 successMessage.data = 'User updated successful';238 return res.status(status.success).send(successMessage);239 } catch (error) {240 errorMessage.error = `Operation was not successful ${error}`;241 return res.status(status.error).send(errorMessage);242 }243};244exports.deleteUser = async (req, res) => {245 const deletedUserId = Path.basename(req.params.id);246 if (req.user.id != deletedUserId && !req.user.admin) {247 errorMessage.error = 'You can`t delete this Users';248 return res.status(status.unauthorized).send(errorMessage);249 }250 try {251 const data = await User.destroy({252 where: {253 id: deletedUserId254 }255 });256 if (data != 1) {257 errorMessage.error = `User with id: ${deletedUserId} do not exists`;258 return res.status(status.notfound).send(errorMessage);259 }260 successMessage.data = 'User deleted successful'261 return res.status(status.success).send(successMessage);262 } catch (error) {263 errorMessage.error = `Operation was not successful ${error}`;264 return res.status(status.error).send(errorMessage);265 }266};267exports.allUsersList = async (req, res) => {268 if (!req.user.admin) {269 errorMessage.error = 'You are unauthorized to get Users List';270 return res.status(status.unauthorized).send(errorMessage);271 }272 try {273 const data = await User.findAll();274 successMessage.data = []275 data.forEach(element => {276 successMessage.data.push({277 id: element.id,278 email: element.email,279 firstname: element.first_name,280 lastname: element.last_name,281 admin: element.is_admin282 });283 });284 return res.status(status.success).send(successMessage);285 } catch (error) {286 errorMessage.error = `Operation was not successful ${error}`;287 return res.status(status.error).send(errorMessage);288 }...

Full Screen

Full Screen

projet.ts

Source:projet.ts Github

copy

Full Screen

1// import * as EmailValidator from 'email-validator';2import { Profil } from './profil';3export class Projet {4 public type_organisation: string;5 public titre_projet: string;6 public porteur_id: number;7 public pays: string;8 public departement: string;9 public email: string;10 public commune: string;11 public categorie: string;12 public montant_collecter: number;13 public duree_campagne: string;14 public description_projet: string;15 public contrepartie: string;16 public resume: string;17 public document_projet: File;18 public description: string;19 public montant: number;20 public quantite: boolean = false;21 public date_livraison: Date;22 public message: string;23 public mode: string;24 public contact: string;25 public reference: string;26 public porteur: Profil;27 private errorMessage: string;28constructor(){29 this.errorMessage = "";30}31//get error message32getErrorMessage(): string {33 return this.errorMessage;34}//end getErrorMessage35//check for save36canUpdate(): boolean {37 //type_organisation38 if(this.type_organisation === undefined || this.type_organisation === null){39 this.errorMessage = "Veuillez sélectionner le type d'organisation"; return false;40 }41 //titre_projet42 if(this.titre_projet === undefined || this.titre_projet === null || this.titre_projet.trim() === ""){43 this.errorMessage = "Veuillez saisir le titre du projet"; return false;44 }45 //pays46 if(this.pays === undefined || this.pays === null ){ //|| this.pays.trim() === ""47 this.errorMessage = "Veuillez sélectionner le pays"; return false;48 }else{49 // if (this.pays === "Benin" ){50 // //departement51 // if(this.departement === undefined || this.departement === null || this.departement.trim() === ""){52 // this.errorMessage = "Veuillez selectionner le departement"; return false;53 // }54 // //commune55 // if(this.commune === undefined || this.commune === null || this.commune.trim() === ""){56 // this.errorMessage = "Veuillez selectionner la commune"; return false;57 // }58 // }59 } 60 //categorie61 if(this.categorie === undefined || this.categorie === null){62 this.errorMessage = "Veuillez sélectionner la catégorie du projet"; return false;63 }64 //montant_collecter65 if(this.montant_collecter === undefined || this.montant_collecter === null){66 this.errorMessage = "Veuillez saisir le montant à collecter pour le projet"; return false;67 }68 69 //duree_campagne70 if(this.duree_campagne === undefined || this.duree_campagne === null){71 this.errorMessage = "Veuillez saisir le nombre de jours de la durée de campagne du projet"; return false;72 }73 //resume74 if(this.resume === undefined || this.resume === null){75 this.errorMessage = "Veuillez saisir la phrase d'accroche"; return false;76 }77 78 //description_projet79 if(this.description_projet === undefined || this.description_projet === null || this.description_projet.trim() === ""){80 this.errorMessage = "Veuillez saisir la présentation détaillée"; return false;81 }82 // //email83 // if(this.email === undefined || this.email === null || this.email.trim() === ""){84 // this.errorMessage = "Veuillez saisir adresse email"; return false;85 86 // }else{87 // let checkEmail : boolean = EmailValidator.validate(this.email.trim());88 // if (checkEmail === false){89 // this.errorMessage = "Cette adresse email n'est pas valide"; return false;90 // }91 // }92 93 94 95 96 97 98 // //contrepartie99 // if(this.contrepartie === undefined || this.contrepartie === null || this.contrepartie.trim() === ""){100 // this.errorMessage = "Veuillez saisir les contreparties de votre projet"; return false;101 // }102 return true;103}//end canUpdate 104 105//check for save106savePartage(): boolean {107 //mode108 if(this.mode === undefined || this.mode === null){109 this.errorMessage = "Veuillez selectionner le mode de partage"; return false;110 }111 112 //message113 if(this.message === undefined || this.message === null || this.message.trim() === ""){114 this.errorMessage = "Veuillez saisir votre message"; return false;115 }116 return true;117}//end canSave118//check for save119canSaveContrepartie(): boolean {120 //type_organisation121 if(this.montant === undefined || this.montant === null){122 this.errorMessage = "Veuillez saisir le montant"; return false;123 }124 125 //titre_projet126 if(this.description === undefined || this.description === null || this.description.trim() === ""){127 this.errorMessage = "Veuillez saisir votre description"; return false;128 }129 //montant_collecter130 if(this.date_livraison === undefined || this.date_livraison === null){131 this.errorMessage = "Veuillez selectionner la date de livraison"; return false;132 }133 return true;134}//end canSave135//check for save136canSave(): boolean {137 //type_organisation138 if(this.type_organisation === undefined || this.type_organisation === null){139 this.errorMessage = "Veuillez sélectionner le type d'organisation"; return false;140 }141 142 //email143 if(this.email === undefined || this.email === null || this.email.trim() === ""){144 this.errorMessage = "Veuillez saisir adresse email"; return false;145 146 }147 // else{148 // let checkEmail : boolean = EmailValidator.validate(this.email.trim());149 // if (checkEmail === false){150 // this.errorMessage = "Cette adresse email n'est pas valide"; return false;151 // }152 // }153 //titre_projet154 if(this.titre_projet === undefined || this.titre_projet === null || this.titre_projet.trim() === ""){155 this.errorMessage = "Veuillez saisir le titre du projet"; return false;156 }157 158 //pays159 if(this.pays === undefined || this.pays === null || this.pays.trim() === ""){160 this.errorMessage = "Veuillez sélectionner le pays"; return false;161 }else{162 if (this.pays === "Benin" ){163 //departement164 if(this.departement === undefined || this.departement === null || this.departement.trim() === ""){165 this.errorMessage = "Veuillez selectionner le departement"; return false;166 }167 //commune168 if(this.commune === undefined || this.commune === null || this.commune.trim() === ""){169 this.errorMessage = "Veuillez selectionner la commune"; return false;170 }171 }172 }173 174 175 //categorie176 if(this.categorie === undefined || this.categorie === null || this.categorie.trim() === ""){177 this.errorMessage = "Veuillez sélectionner la catégorie du projet"; return false;178 }179 180 //montant_collecter181 if(this.montant_collecter === undefined || this.montant_collecter === null){182 this.errorMessage = "Veuillez saisir le montant à collecter pour le projet"; return false;183 }184 //duree_campagne185 if(this.duree_campagne === undefined || this.duree_campagne === null){186 this.errorMessage = "Veuillez indiquer le nombre de jours de la durée de campagne du projet"; return false;187 }188 189 //description_projet190 if(this.description_projet === undefined || this.description_projet === null || this.description_projet.trim() === ""){191 this.errorMessage = "Veuillez saisir la description du projet"; return false;192 }193 //contrepartie194 if(this.contrepartie === undefined || this.contrepartie === null || this.contrepartie.trim() === ""){195 this.errorMessage = "Veuillez saisir les contreparties de votre projet"; return false;196 }197 return true;198}//end canSave 199 200 ...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var strykerParent = require('stryker-parent');2var errorMessage = strykerParent.errorMessage;3var errorMessage = require('stryker-parent').errorMessage;4import { errorMessage } from 'stryker-parent';5import strykerParent from 'stryker-parent';6var errorMessage = strykerParent.errorMessage;7import * as strykerParent from 'stryker-parent';8var errorMessage = strykerParent.errorMessage;9import * as strykerParent from 'stryker-parent';10var errorMessage = strykerParent.errorMessage;11var strykerParent = require('stryker-parent');12var errorMessage = strykerParent.errorMessage;13var errorMessage = require('stryker-parent').errorMessage;14import { errorMessage } from 'stryker-parent';15import strykerParent from 'stryker-parent';16var errorMessage = strykerParent.errorMessage;17import * as strykerParent from 'stryker-parent';18var errorMessage = strykerParent.errorMessage;19import * as strykerParent from 'stryker-parent';20var errorMessage = strykerParent.errorMessage;21var strykerParent = require('stryker-parent');22var errorMessage = strykerParent.errorMessage;23var errorMessage = require('stryker-parent').errorMessage;24import { errorMessage } from 'stryker-parent';25import strykerParent from 'stryker-parent';26var errorMessage = strykerParent.errorMessage;27import * as strykerParent from 'stryker-parent';28var errorMessage = strykerParent.errorMessage;

Full Screen

Using AI Code Generation

copy

Full Screen

1var strykerParent = require('stryker-parent');2var errorMessage = strykerParent.errorMessage;3console.log(errorMessage('test'));4var strykerParent = require('stryker-parent');5var errorMessage = strykerParent.errorMessage;6console.log(errorMessage('test2'));7var strykerParent = require('stryker-parent');8var errorMessage = strykerParent.errorMessage;9console.log(errorMessage('test3'));10var strykerParent = require('stryker-parent');11var errorMessage = strykerParent.errorMessage;12console.log(errorMessage('test4'));13var strykerParent = require('stryker-parent');14var errorMessage = strykerParent.errorMessage;15console.log(errorMessage('test5'));16var strykerParent = require('stryker-parent');17var errorMessage = strykerParent.errorMessage;18console.log(errorMessage('test6'));19var strykerParent = require('stryker-parent');20var errorMessage = strykerParent.errorMessage;21console.log(errorMessage('test7'));22var strykerParent = require('stryker-parent');23var errorMessage = strykerParent.errorMessage;24console.log(errorMessage('test8'));25var strykerParent = require('stryker-parent');26var errorMessage = strykerParent.errorMessage;27console.log(errorMessage('test9'));28var strykerParent = require('stryker-parent');29var errorMessage = strykerParent.errorMessage;30console.log(errorMessage('test10'));31var strykerParent = require('stryker-parent');32var errorMessage = strykerParent.errorMessage;33console.log(errorMessage('test11'));

Full Screen

Using AI Code Generation

copy

Full Screen

1var stryker = require('stryker-parent');2var message = stryker.errorMessage('some error');3console.log(message);4var stryker = require('stryker-parent');5var message = stryker.errorMessage('some error');6console.log(message);7var stryker = require('stryker-parent');8var message = stryker.errorMessage('some error');9console.log(message);10var stryker = require('stryker-parent');11var message = stryker.errorMessage('some error');12console.log(message);13var stryker = require('stryker-parent');14var message = stryker.errorMessage('some error');15console.log(message);16var stryker = require('stryker-parent');17var message = stryker.errorMessage('some error');18console.log(message);19var stryker = require('stryker-parent');20var message = stryker.errorMessage('some error');21console.log(message);22var stryker = require('stryker-parent');23var message = stryker.errorMessage('some error');24console.log(message);25var stryker = require('stryker-parent');26var message = stryker.errorMessage('some error');27console.log(message);28var stryker = require('stryker-parent');29var message = stryker.errorMessage('some error');30console.log(message);31var stryker = require('stryker-parent');32var message = stryker.errorMessage('some error');33console.log(message);34var stryker = require('stryker-parent');

Full Screen

Using AI Code Generation

copy

Full Screen

1const errorMessage = require('stryker-parent').errorMessage;2console.log(errorMessage('This is an error message.'));3const errorMessage = require('stryker-parent').errorMessage;4console.log(errorMessage('This is an error message.'));514:12:13 (1015) INFO MutatorFacade 1 Mutant(s) generated614:12:13 (1015) INFO SandboxPool Creating 1 test runners (based on CPU count)714:12:13 (1015) INFO Sandbox Creating a sandbox for test runner 0814:12:14 (1015) INFO MutatorFacade 1 Mutant(s) generated914:12:14 (1015) INFO SandboxPool Creating 1 test runners (based on CPU count)1014:12:14 (1015) INFO Sandbox Creating a sandbox for test runner 01114:12:15 (1015) INFO MutatorFacade 1 Mutant(s) generated1214:12:15 (1015) INFO SandboxPool Creating 1 test runners (based on CPU count

Full Screen

Using AI Code Generation

copy

Full Screen

1var stryker = require('stryker-parent');2var message = stryker.errorMessage('test');3console.log(message);4var stryker = require('stryker-parent');5var message = stryker.errorMessage('index');6console.log(message);7var stryker = require('stryker-parent');8var message = stryker.errorMessage('stryker.conf');9console.log(message);10var stryker = require('stryker-parent');11var message = stryker.errorMessage('package');12console.log(message);13var stryker = require('stryker-parent');14var message = stryker.errorMessage('tsconfig');15console.log(message);16var stryker = require('stryker-parent');17var message = stryker.errorMessage('tsconfig');18console.log(message);19var stryker = require('stryker-parent');20var message = stryker.errorMessage('gitignore');21console.log(message);22var stryker = require('stryker-parent');23var message = stryker.errorMessage('gitignore');24console.log(message);25var stryker = require('stryker-parent');26var message = stryker.errorMessage('gitignore');27console.log(message);28var stryker = require('stryker-parent');29var message = stryker.errorMessage('gitignore');30console.log(message);31var stryker = require('stryker-parent');32var message = stryker.errorMessage('gitignore');33console.log(message);

Full Screen

Using AI Code Generation

copy

Full Screen

1const {errorMessage} = require('stryker-parent');2console.log(errorMessage);3const {errorMessage} = require('stryker-parent');4console.log(errorMessage);5const {errorMessage} = require('stryker-parent');6console.log(errorMessage);7const {errorMessage} = require('stryker-parent');8console.log(errorMessage);9const {errorMessage} = require('stryker-parent');10console.log(errorMessage);11const {errorMessage} = require('stryker-parent');12console.log(errorMessage);13const {errorMessage} = require('stryker-parent');14console.log(errorMessage);15const {errorMessage} = require('stryker-parent');16console.log(errorMessage);17const {errorMessage} = require('stryker-parent');18console.log(errorMessage);19const {errorMessage} = require('stryker-parent');20console.log(errorMessage);21const {errorMessage} = require('stryker-parent');22console.log(errorMessage);

Full Screen

Using AI Code Generation

copy

Full Screen

1module.exports = function () {2 return strykerParent.errorMessage("some error message");3}4const strykerParent = require('stryker-parent');5module.exports = function () {6 return strykerParent.errorMessage("some error message");7}8const errorMessage = require('stryker-parent').errorMessage;9module.exports = function () {10 return errorMessage("some error message");11}12const { errorMessage } = require('stryker-parent');13module.exports = function () {14 return errorMessage("some error message");15}16const { errorMessage: errorMessage } = require('stryker-parent');17module.exports = function () {18 return errorMessage("some error message");19}20const { errorMessage: errorMessage } = require('stryker-parent');21module.exports = function () {22 return errorMessage("some error message");23}24const strykerParent = require('stryker-parent');25module.exports = function () {26 return strykerParent.errorMessage("some error message");27}28const errorMessage = require('stryker-parent').errorMessage;29module.exports = function () {30 return errorMessage("some error message");31}32const { errorMessage } = require('stryker-parent');33module.exports = function () {34 return errorMessage("some error message");35}36const { errorMessage: errorMessage } = require('stryker-parent');37module.exports = function () {38 return errorMessage("some error message");39}40const strykerParent = require('stryker-parent');41module.exports = function () {42 return strykerParent.errorMessage("some error message");43}

Full Screen

Automation Testing Tutorials

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.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run stryker-parent automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful