Url shortener service - Tests failing for unknown reason

I’ve done manual tests which show my solution should work at least partly, however none of the tests is passed with the auto-grader.

Could anyone guess why?

Here is my code:

require('dotenv').config();
var bodyParser = require('body-parser');
const express = require('express');
const cors = require('cors');
const dns = require('dns');
const app = express();

var mongoose = require('mongoose');
mongoose.connect(process.env['MONGO_URI'], { useNewUrlParser: true, useUnifiedTopology: true });


const Schema = mongoose.Schema;

const urlSchema = new Schema({
  original_url: { type: String, required: true },
  short_url: { type: Number, required: true }
});

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

mongoose.connection.on('error', function(error) {
  console.log(error);
});
mongoose.connection.on('open', function() {
  console.log('Connected to MongoDB database.');
});

// 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.post('/api/shorturl', bodyParser.urlencoded({ extended: false }), (req, res) => {
  const url = req.body.url;
  let responseObj = { start: 'start' };
  let shortUrl = 1;

  const prefix = /^https?:\/\//;
  if (prefix.test(url)) {
    const domain = url.replace(prefix, "");
    console.log('domain:', domain);
    dns.lookup(domain, async (err, address) => {
      if (err) {
        res.json({ error: 'invalid url' });
        return;
      }
      else {
        try {
          console.log('found domain ', domain);
          let urlFound = await Url.findOne({original_url:url});
          if (urlFound) {
            console.log('found ', urlFound);
            res.json({original_url: url, short_url: urlFound.short_url});
          } else {
            let withGreatestId = await Url.find({})
                                      .sort({ short_url: -1 })
                                      .limit(1);
                                      // [0]
                                      // .short_url;
            console.log('greatestId[0].short_url: ', withGreatestId[0].short_url);
            let newUrl = await Url.create({
                            original_url: url,
                            short_url: withGreatestId[0].short_url + 1
                      });
            res.json({
                original_url: newUrl.original_url,
                short_url: newUrl.short_url });
          }
        } catch(err) {
          console.log(err);
        }
      }
    });
  }  else {
    res.json({ error: 'invalid url' });
    return;
  }
});

app.get("/api/shorturl/:shortUrlId", async (req, res) => {
  try {
    // look up shortUrl in db
    let address = await Url.findOne({ short_url: req.params.shortUrlId });
    console.log('address', address);
    // redirect to shorturl initial url address
    res.redirect(address.original_url);
  } catch (err) {
    res.json({ error: "invalid url" });
  }
});


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

Your project link(s)

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

Your browser information:

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

Challenge: URL Shortener Microservice

Link to the challenge:

What happens here if url = "https://forum.freecodecamp.org/t/url-shortener-service-tests-failing-for-unknown-reason/490188", for instance?

Hmmm…
dns.lookup only looks up for the domain (as its name indicates), not the subdirectories.
I’ve just replaced

const domain = url.replace(prefix, "");

by

 const domain = url.replace(prefix, "")
                   .split('/')
                   [0];

And I get the tests passed.
But my solution is not strictly correct, as it would redirect to links that may not exist (like https://www.google.com/something).

Would it be a better solution to not use the dns module at all, and instead simply create an XMLHttpRequest, apply the GET method and check the status code?

Otherwise, thanks for your answer (I was not expecting to get it so quickly).

I think that would be a more advanced test than what’s expected here. Besides, the spec only says a valid URL, not a working one (links die all the time). Most people just check the https?:// bit in the end anyway but I’ve always preferred the dns.lookup() solution.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.