Issue with mocking ajax request - mockjax

I am writing a test for webclient viewmodel in Qunit and used Mockjax for moking ajax request, but it seems i am doing something wrong while moking, please help me to solve the following problem.
function WebmailViewModel() {
// Data
var self = this;
self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenMailData = ko.observable();
// Behaviours
self.goToFolder = function(folder) {
self.chosenFolderId(folder);
self.chosenMailData(null); // Stop showing a mail
$.post('/mail', { folder: folder }, function(returnedData) {
self.chosenFolderData(returnedData);
});
}
self.goToMail = function(mail) {
self.chosenFolderId(mail.folder);
self.chosenFolderData(null); // Stop showing a folder
$.get("/mail", { mailId: mail.id }, self.chosenMailData);
};
self.goToFolder('Inbox');
};
$(function() {
ko.applyBindings(new WebmailViewModel());
});
test("web mail client test", function() {
stop(2);
var returnedData = {
"from": "deba#tieto.com",
"to": "test1#tieto.com",
"subject": "Subject1",
"date": "22/05/2014"
};
vm = new WebmailViewModel();
$.mockjax({
url: "/mail",
contentType: "application/json",
responseTime: 0,
response: function (settings) {
this.responseText = {"from": "deba#xyz.com", "to": "test1#xyz.com", "subject":"Subject1", "date":"22/05/2014"};
start();
}
});
vm.goToFolder('Inbox');
setTimeout(function() {
deepEqual(vm.chosenFolderData,returnedData, "Two objects can be the same in value" );
start();
}, 150);
});
Test Result:
Two objects can be the same in valueExpected: {
"date": "22/05/2014",
"from": "deba#tieto.com",
"subject": "Subject1",
"to": "test1#tieto.com"
}
Result: function c( ){
[code]
}
Diff: {
"date": "22/05/2014",
"from": "deba#tieto.com",
"subject": "Subject1",
"to": "test1#tieto.com"
function c( ){
[code]
}
Source: at Anonymous function (file:///C:/Users/dasssdeb/Desktop/JS%20Tests/QUnit/tests/tests.js:174:8)
I belive issue is with moking the ajax request. please help me with your valuable experience.

Your mockjax setup must come before your source code. In the code above you initialize the WebmailViewModel (which performs ajax requests) before you set up the mockjax request handler. Try structuring things like this instead:
// SOURCE CODE
// in your source code you will need to have a callback for your WebmailViewModel method arguments...
function WebmailViewModel() {
// ...
// Behaviours
self.goToFolder = function(folder, callback) {
self.chosenFolderId(folder);
self.chosenMailData(null); // Stop showing a mail
$.post('/mail', { folder: folder }, function(returnedData) {
self.chosenFolderData(returnedData);
callback(returnedData);
});
}
self.goToMail = function(mail) {
self.chosenFolderId(mail.folder);
self.chosenFolderData(null); // Stop showing a folder
$.get("/mail", { mailId: mail.id }, function(returnedData) {
self.chosenMailData(returnedData);
callback(returnedData);
});
};
};
Now you can create your test code with callbacks when they finish to hook your assertions into...
// TEST CODE
// Set up the request handler first...
$.mockjax({
url: "/mail",
contentType: "application/json",
responseTime: 0,
response: function (settings) {
this.responseText = {"from": "deba#xyz.com", "to": "test1#xyz.com", "subject":"Subject1", "date":"22/05/2014"};
}
});
// then create your test...
test("web mail client test", function() {
stop();
var returnedData = {
"from": "deba#tieto.com",
"to": "test1#tieto.com",
"subject": "Subject1",
"date": "22/05/2014"
};
vm = new WebmailViewModel();
vm.goToFolder('Inbox', function(returnedData) {
// this is the callback for when going to the folder finishes...
deepEqual(vm.chosenFolderData, returnedData, "Two objects can be the same in value" );
start();
});
});

Related

How to resolve Cloud Function Error:401 Unauthorized

I have coded an Apps Script that creates an event in the Calendar.
Apps Script is stand alone, and event in also created in my personal Gmail account.
This Script is linked to GCP project linked to same account as Script.
Oauth consent screen is created in the GCP account and also credentials for Oauth2.0 client ID.
Now I created a cloud function to call this appsScript but it is giving an Error:401
following is code for the cloud function
let message = req.query.message || req.body.message || 'Hello World!';
const axios = require('axios');
const {google} = require('googleapis');
//Authorization
const { GoogleAuth } = require('google-auth-library');
const auth1 = new GoogleAuth({
keyFile: 'credentials.json',
scopes: ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.metadata'
, 'https://www.googleapis.com/auth/calendar','https://www.googleapis.com/auth/calendar.events' ],
});
const drive = google.drive({version: 'v3', auth: auth1 });
const calendar = google.calendar({version : "v3"});
//calling formSchedule function with all the variables
async function formSchedule(eventDate,claimId, garageId, claimDet,startTime,cEmailG){
//Schedule Meeting Json Data
var evDurtion=30;
var startDateTime = startTime;
var endDateTime=new Date(startDateTime.getTime()+(evDurtion*60000));
// console.log(endDateTime)
var subject="Claim ID : "+claimId+' - Call';
var attendees=[{
"email": garageId,
},
];
var eventData={
"summary":subject,
'start': {
'dateTime': startDateTime,
'timeZone': 'Asia/Kolkata'
},
'end': {
'dateTime': endDateTime,
'timeZone': 'Asia/Kolkata'
},
"attendees":attendees,
"conferenceData": {
"createRequest": {
"conferenceSolutionKey": {
"type": "hangoutsMeet"
},
"status": {
"statusCode": "success"
},
"requestId": "test1235"
}
},
"description":claimDet,
"defaultReminders": [
{
"method": "popup",
"minutes": "5"
}
]
}
console.log("after all variables initialization")
// Schedule Meeting
axios({
method: "post",
url : //API Executable deployed Apps Script link,
data: {
'eventdata' : eventData,
'serviceId' : cEmailG
},
headers: {
'Content-Type': 'text/plain;charset=utf-8',
},
}).then(function (response) {
try{
console.log('Event Added Successfully.')
}
catch (error){
console.log('------error-----',error)
}
})
}
res.status(200).send(message);
};```

How to get response and show from backend in vue js

I have the following code:
data: function () {
return {
searchResults: []
}
methods: {
show() {
return axios({
method: 'get',
url: this.url,
headers: {
'Authorization': `Bearer ${localStorage.getItem('user-token')}`
}
})
.then (function (response){
return response.data['searchResults'];
})
.catch(e => { console.log(e) })
},
}
I have an onClick button. When I click the button, the show function executed and it send get response to my spring boot. After that it retrieves some data as I see in console, but the data is not displayed in browser. How can I fix it? The data I get looks like this:
JSON:
0: Object { "Code": "4326", code_color: 2, "name": "SomeName", … }
1: Object { "Code": "4326", code_color: 2, "name": "SomeName", … }
2: Object { "Code": "4326", code_color: 2, "name": "SomeName", … }
You should assign the returned data from api call in the show method to searchResults in the components data, so instead of
return response.data['searchResult']
you can use
this.searchResults = response.data.searchResult

Send additional info to server in uploading image process

im using filepond 4.25.1 on vue 2.6.11 and everything work without problem until now.
i want to send additional information to my server which is aspnet core 3. i send my request from filepond like below
myServer: {
url: "http://**********/api/CustomerAuth/",
process: {
url: "uploadimages",
method: "POST",
withCredentials: false,
headers: {},
data: {
nationalcode: "1234567890",
typecode:"1"
},
timeout: 7000,
},
load: (source, load) => {
fetch(source)
.then((res) => res.blob())
.then(load);
},
}
and server side
[HttpPost("uploadimages")]
public IActionResult UploadImages()
{
try
{
var file = Request.Form.Files[0];
string folderName = "Upload";
string webRootPath = _hostingEnvironment.WebRootPath;
string newPath = Path.Combine(webRootPath, folderName);
if (!Directory.Exists(newPath))
{
Directory.CreateDirectory(newPath);
}
if (file.Length > 0)
{
string fileName =
ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
string fullPath = Path.Combine(newPath, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
}
}
return Ok("Upload Successful");
}
catch (System.Exception ex)
{
return NotFound(new { img_upld_error = ex.Message });
}
}
in server side i need to access "nationalcode" and "typecode" which is send as data in process and value of these two parameters always change so its not static value and with interact of user value of this two always change.
I really appreciated if someone give me a some clue or guide me to solve my problem.
FilePond dev here.
data does not exist as a prop on process.
You can add additional FormData parameters with the ondata property. See updated example below:
myServer: {
url: "http://**********/api/CustomerAuth/",
process: {
url: "uploadimages",
method: "POST",
withCredentials: false,
headers: {},
data: {
nationalcode: "1234567890",
typecode:"1"
},
ondata: (formData) => {
formData.append('nationalcode', '1234567890');
formData.append('typecode', '1');
return formData;
}
timeout: 7000,
},
load: (source, load) => {
fetch(source)
.then((res) => res.blob())
.then(load);
},
}
Alternatively you can use the filepond metadata plugin to add metadata to each file (this is automatically sent to the server).
https://pqina.nl/filepond/docs/patterns/plugins/file-metadata/
FilePond.setOptions({
fileMetadataObject: {
'nationalcode': '1234567890',
'typecode': '1'
}
})
You can get file's in model, define your model like this
public class FileWithDataModel
{
public IFormFile File { get; set; }
public string NationalCode { get; set; }
public string TypeCode { get; set; }
}
and controller method will be :
public async Task<IActionResult> UploadFileWithData(FileWithDataModel model)
{
var file = model.File;
//you can save this file...
var nCode = model.NationalCode; //can access data easy
//......
return Ok();
}
Microsoft suggest to use Async method especially for file processing and uploading
here is example of jquery client
var form = new FormData();
form.append("NationalCode", "12345678");
form.append("TypeCode", "1");
form.append("File", fileInput.files[0], "/path/to/file");
var settings = {
"url": "http://**********/api/CustomerAuth/",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});

Fetch data in real time with flutter

I have an issue in my app that fetches data by getting it from another website. I want my screen to show the data in real time so if any changes happened on the website, it shows the changes in my app without the need to click on update or do any other action.
I tried to use future but I don't know how to use it. This is my code:
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
class FetchDataAPI {
get(String url, String function, Map<String, String> header) async {
List Response = List();
Response.clear();
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
// Internet connected
try {
var resBody = await http.get(
url,
headers: header,
);
print(resBody.statusCode);
// 200
if (resBody.statusCode == 200) {
Response = [json.decode(resBody.body)];
return Response ;
}
// Not 200
else {
Response = [
{
"exception": false,
"statusCode": resBody.statusCode,
// Body here depend on response post man
"body": json.decode(resBody.body),
"message": null
}
];
return Response;
}
} catch (e) {
Response = [
{
"exception": true,
"statusCode": null,
"body": null,
"message": e.toString()
}
];
return Response;
}
} else {
// Internet not connected
Response = [
{
"exception": true,
"statusCode": null,
"body": null,
"message": "No internet conected."
}
];
return Response;
}
} on SocketException catch (e) {
Response = [
{
"exception": true,
"statusCode": null,
"body": null,
"message": "No internet conected."
}
];
return Response;
}
}
}
You should use Streams, alongside StreamBuilder

Alexa Skills: Lambda function to read contents from a file in S3

I have an Alexa Skill that tries to read the contents from a file stored in S3. The test event for the Lambda function for Alexa Start Session is successful. I understand that there is something wrong with my CompletedMyIntentHandler but I can't quite seem to figure it out. Any help on it is much appreciated. The lambda function takes help from https://github.com/alexa/alexa-cookbook/blob/master/aws/Amazon-S3/read/. Find my Lambda function below;
const Alexa = require('ask-sdk');
// 1. Text strings =====================================================================================================
// Modify these strings and messages to change the behavior of your Lambda function
const helpOutput = 'You can demonstrate the S3 Storage read capability by saying "Hello".';
const helpReprompt = 'Try saying "Hello World".';
var myBucket = 'jailalita'; // replace with your own bucket name!
var myObject = 'hello.txt'; // replace with your own file name!
// 2. Intent Handlers =============================================
const CompletedMyIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'MyIntent';
},
handle(handlerInput) {
console.log('My Intent - handle');
const responseBuilder = handlerInput.responseBuilder;
const speechOutput = MyIntent();
return responseBuilder
.speak(speechOutput)
.getResponse();
},
};
const HelpHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
return responseBuilder
.speak(helpOutput)
.reprompt(helpReprompt)
.getResponse();
},
};
const CancelStopHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && (request.intent.name === 'AMAZON.CancelIntent' || request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
const speechOutput = 'Okay, talk to you later! ';
return responseBuilder
.speak(speechOutput)
.withShouldEndSession(true)
.getResponse();
},
};
const SessionEndedHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
const request = handlerInput.requestEnvelope.request;
console.log(`Original Request was: ${JSON.stringify(request, null, 2)}`);
console.log(`Error handled: ${error}`);
return handlerInput.responseBuilder
.speak('Sorry, I can not understand the command. Please say again.')
.reprompt('Sorry, I can not understand the command. Please say again.')
.getResponse();
},
};
// 3. Helper Function =================================================================================================
function MyIntent() {
var myParams = {
Bucket: myBucket,
Key: myObject
};
S3read(myParams, myResult => {
console.log("sent : " + JSON.stringify(myParams));
console.log("received : " + myResult);
var speech = this.response.speak('The S 3 file says, ' + myResult );
return speech;
}
);
}
function S3read(params, callback) {
// call AWS S3
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
s3.getObject(params, function(err, data) {
if(err) { console.log(err, err.stack); }
else {
var fileText = data.Body.toString(); // this is the complete file contents
callback(fileText);
}
});
}
// 4. Exports handler function and setup ===================================================
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
//LaunchRequestHandler,
CompletedMyIntentHandler,
HelpHandler,
CancelStopHandler,
SessionEndedHandler,
)
.addErrorHandlers(ErrorHandler)
.lambda();
JSON Input
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.e6f74d95-8d55-4aac-ade0-dd4ff4ed4f04",
"application": {
"applicationId": "amzn1.ask.skill.5edd47bc-525d-4ef4-9b6e-a83a7e79744f"
},
"user": {
"userId": "amzn1.ask.account.AF4SLRK5TC4SDSHL7LGK2IB6SMXCPGS7Y6YKYLPDGWRE7CA3K6MCKVVUW2OFMVCWJFXZDQBSYY5Z2RXZWQAJLDCMR3SXYCVA7ZARDRNQXA3TXBM4ILP77FKNOO4MCVPLWHIXW3QNZCRYPDQ7CCBP6QT7GMTBMQX2BVCNS22SZL4MC6WB7GDS44XN2DKGJQBMGIDQ3O7RBYD6GAI"
}
},
"context": {
"System": {
"application": {
"applicationId": "amzn1.ask.skill.5edd47bc-525d-4ef4-9b6e-a83a7e79744f"
},
"user": {
"userId": "amzn1.ask.account.AF4SLRK5TC4SDSHL7LGK2IB6SMXCPGS7Y6YKYLPDGWRE7CA3K6MCKVVUW2OFMVCWJFXZDQBSYY5Z2RXZWQAJLDCMR3SXYCVA7ZARDRNQXA3TXBM4ILP77FKNOO4MCVPLWHIXW3QNZCRYPDQ7CCBP6QT7GMTBMQX2BVCNS22SZL4MC6WB7GDS44XN2DKGJQBMGIDQ3O7RBYD6GAI"
},
"device": {
"deviceId": "amzn1.ask.device.AETD2DDUWNTWA5BNNDFHCRT26SLOZUTZUFJ5P3OEQGDCWWDSFWPKNONGMT4KZAJPUB6ZRD3YVCDEVFAGPLXHVP6XESWS6BKEYZHZRXT25QNK2RTFNUG4PKD347P5DAWE2H4WQLGTQVLNQ5JNFGHFUSUC3X7Q",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLjVlZGQ0N2JjLTUyNWQtNGVmNC05YjZlLWE4M2E3ZTc5NzQ0ZiIsImV4cCI6MTUzMDUxMzU2NCwiaWF0IjoxNTMwNTA5OTY0LCJuYmYiOjE1MzA1MDk5NjQsInByaXZhdGVDbGFpbXMiOnsiY29uc2VudFRva2VuIjpudWxsLCJkZXZpY2VJZCI6ImFtem4xLmFzay5kZXZpY2UuQUVURDJERFVXTlRXQTVCTk5ERkhDUlQyNlNMT1pVVFpVRko1UDNPRVFHRENXV0RTRldQS05PTkdNVDRLWkFKUFVCNlpSRDNZVkNERVZGQUdQTFhIVlA2WEVTV1M2QktFWVpIWlJYVDI1UU5LMlJURk5VRzRQS0QzNDdQNURBV0UySDRXUUxHVFFWTE5RNUpORkdIRlVTVUMzWDdRIiwidXNlcklkIjoiYW16bjEuYXNrLmFjY291bnQuQUY0U0xSSzVUQzRTRFNITDdMR0sySUI2U01YQ1BHUzdZNllLWUxQREdXUkU3Q0EzSzZNQ0tWVlVXMk9GTVZDV0pGWFpEUUJTWVk1WjJSWFpXUUFKTERDTVIzU1hZQ1ZBN1pBUkRSTlFYQTNUWEJNNElMUDc3RktOT080TUNWUExXSElYVzNRTlpDUllQRFE3Q0NCUDZRVDdHTVRCTVFYMkJWQ05TMjJTWkw0TUM2V0I3R0RTNDRYTjJES0dKUUJNR0lEUTNPN1JCWUQ2R0FJIn19.Fc-aAcaf4qTgf489cQsZ44KTq-yZ-xMJCBenq9DbpppkMgSscF0NodGYTK967AcGblwqOFqcwIC1PvGmISER9oDH5TIhKF1kLsTimRHRKsttElRl7FIEvki-sKLD4VTeStTKM-w5laBm6urAzlCXpJySU-InVH5_qE0M5LHnLZRrE_qy7EmIq2vsrq2Cekve-gQ3Y3ImW3_0b7ikg6gwO6si-O0IxXO6hxS5sTuQH4f4aRybHVO3jflHD7g7pGPFzfkpc_tg6KFkhFv6CMvkx25A2u7iO7vVQpMHdj-_2ZM0ZmO9JuP-v7ydKYT_1IDjfpZKfvgIGyYsNfCPDY5F2Q"
}
},
"request": {
"type": "LaunchRequest",
"requestId": "amzn1.echo-api.request.12ef23e3-a7e5-48a4-90f9-de9c253f72b9",
"timestamp": "2018-07-02T05:39:24Z",
"locale": "en-US",
"shouldLinkResultBeReturned": false
}
}
JSON Output
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can not understand the command. Please say again.</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can not understand the command. Please say again.</speak>"
}
},
"shouldEndSession": false
},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.0 Node/v8.10.0"
}
}
JSON Editor
{
"interactionModel": {
"languageModel": {
"invocationName": "hello world",
"intents": [
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "MyIntent",
"slots": [],
"samples": [
"hello"
]
}
],
"types": []
}
}
}
You can't build your response and return inside the S3Read function as it's an async call to an external service. You need to wait for that call using async/await and once you get a value then craft the response and return.