URL Shortener Microservice - Tests Timing Out

Tell us what’s happening:
When I submit my code all of the tests time out (except the first test). Also when I put a website in the input and click the post url button, it does nothing, but when I type random letters it works the way it should.

My Code

require('dotenv').config();
const express = require('express');
const cors = require('cors');
const app = express();
const mongo = require('mongodb');
const mongoose = require('mongoose');

// Basic Configuration
const port = process.env.PORT || 3000;

app.use(cors());

app.use('/public', express.static(`${process.cwd()}/public`));

app.get('/', function(req, res) {
  res.sendFile(process.cwd() + '/views/index.html');
});

// Your first API endpoint
app.get('/api/hello', function(req, res) {
  res.json({ greeting: 'hello API' });
});

app.listen(port, function() {
  console.log(`Listening on port ${port}`);
});

const mySecret = process.env['MONGO_URI']

mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });

let urlSchema = new mongoose.Schema({
  original : {type: String, required: true},
  short : Number
})

let Url = mongoose.model('Url', urlSchema)

let bodyParser = require('body-parser')
let responseObject = {}
app.post('/api/shorturl', bodyParser.urlencoded({ extended: false }) , (request, response) => {
  let inputUrl = request.body['url']

  let urlRegex = new RegExp(/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi)
  
  if(!inputUrl.match(urlRegex)){
    response.json({error: 'invalid url'})
    return
  }

  responseObject['original_url'] = inputUrl
  
  let inputShort = 1
  
  Url.findOne({})
        .sort({short: 'desc'})
        .exec((error, result) => {
          if(!error && result != undefined){
            inputShort = result.short + 1
          }
          if(!error){
            Url.findOneAndUpdate(
              {original: inputUrl},
              {original: inputUrl, short: inputShort},
              {new: true, upsert: true },
              (error, savedUrl) => {
                if(!error){
                  responseObject['short_url'] = savedUrl.short
                  response.json(responseObject)
                }
              }
            )
          }
  })
})

app.get('/api/shorturl/:input', (request, response) => {
  let input = request.params.input

  Url.findOne({short: input}, (error, result) => {
    if(!error && result != undefined){
      response.redirect(result.original)
    }else{
      response.json('URL not found')
    }
  })
})

Your project link(s)

solution: https://replit.com/@celestiaimoon/boilerplate-project-urlshortener

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.40

Challenge: URL Shortener Microservice

Link to the challenge:

Modifying your POST route thusly:

app.post('/api/shorturl', async (request, response) => {
  console.log('post');
  console.log(JSON.stringify(request.body));
  console.log(JSON.stringify(request.params));
  console.log(JSON.stringify(request.query));

  let inputUrl = request.body['url']

  let urlRegex = new RegExp(/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi)

  if(!inputUrl.match(urlRegex)){
    response.json({error: 'invalid url'})
    return
  }

  responseObject['original_url'] = inputUrl
  
  let inputShort = 1
  
  Url.findOne({})
        .sort({short: 'desc'})
        .exec((error, result) => {
          if(!error && result != undefined){
            inputShort = result.short + 1
          }
          if(!error){
            Url.findOneAndUpdate(
              {original: inputUrl},
              {original: inputUrl, short: inputShort},
              {new: true, upsert: true },
              (error, savedUrl) => {
                if(!error){
                  responseObject['short_url'] = savedUrl.short
                  console.log(responseObject)
                  return response.json(responseObject)
                }
              }
            )
          }
  })
    console.log('hello');
})

gives output

post
{"url":"https://boilerplate-project-urlshortener-11.jeremyagray.repl.co/?v=1636153103794"}
{}
{}
hello

which means the route is getting hit, the input is there, and that execution is getting through you route to the end without returning a response, hence the timeout. Your Url.findOne({}) code is not working.

Try checking for an existing URL record, and then save the new one if there is no existing one, and then return the necessary info. I think findOne() without a field to match returns any record. I’m also not sure about the .exec(); that usually gets attached to await queries and you’re using callbacks so I would double check that as well. I would disable the validation regular expression until you had the rest working.

You’re also going to have trouble with the short part of the record unless you find a way to make sure they are unique.

That helped me, thank you!