Back End Development and APIs - Url shortener project tests failing

My code seems to be working fine but I can’t get second and third tests to pass.

This is my index.js:

require('dotenv').config();
const express = require('express');
const cors = require('cors');
const app = express();
const bodyParser = require("body-parser")
const dns = require('node:dns');
const { Console } = require('node:console');
const urlArrays = []

// Basic Configuration
const port = process.env.PORT || 3000;
app.use("/", bodyParser.urlencoded({ extended: false }))

app.use(cors());

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

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

app.post("/api/shorturl", (req, res, next) => {
  let url = req.body.url
  const regex = /^https?:\/\//i
  const regex2 = /\/+$/
  let dnsUrl = url.replace(regex, "")
  dnsUrl = dnsUrl.replace(regex2, "")
  dns.lookup(dnsUrl, (err, address, family) => {
    if (err) {
      res.json({ "error": 'invalid url' })
    } else {
      urlArrays.push(url)
      res.json({ "original_url": url, "short_url": (urlArrays.length - 1) })
    }
  })
})

app.get('/api/shorturl/:id', (req, res) => {
  res.redirect(urlArrays[req.params.id])
})

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

Here’s my source code in case that’s not enough: boilerplate-project-urlshortener - Node.js Repl - Replit

Thank you I appreciate the help

If I enter www.thisisavalidurl.com , I get a response of “invalid url.”

You should get that for two reasons:

  1. It is not a live site
  2. It is not prefixed with http:// or https://

Is it your position (and that of the tests) that a URL that is not currently registered, or a URL that is missing an http:// prefix, should be considered “invalid”?

The tests are wanting to make sure the prefix of http:// or https:// is present in the url submitted.

It is my opinion that a non-live url should also not be considered valid if I were creating the app as one of my projects to showcase for employers.

In that case, I can make three observations:

  1. The project accepts URLs without common prefixes, such as www.google.com or even google.com |EDIT| Not requiring an http:// prefix should not be a problem, as the tests submit several non-prefixed URLs that are expected to be shortened.
  2. The project produces a new short URL each time I enter the same original URL, rather than returning the existing short URL. (I thought this was a test case, but I don’t see it on the assignment page now)
  3. When I attempt to visit a short URL for a link that does not include the http:// prefix, I get the following error:
This page isn’t working
boilerplate-project-urlshortener.martinian.repl.co redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS

|EDIT|
The key issue seems to be that your URL shortener cannot handle anything other than a domain name. It will reject a URL like https://www.reddit.com/r/tea/ or boilerplate-project-urlshortener.martinian.repl.co/?v=1667184004712, which is one of the URLs that may be submitted by the test.

Thank you! The issue was indeed that it could handle only domain names.

I solved it by changing my POST handler to :

app.post("/api/shorturl", (req, res, next) => {
  let url = req.body.url
  dns.lookup(new URL(url).hostname, (err, address, family) => {
    if (err) {
      console.log(err)
      res.json({ "error": 'invalid url' })
    } else {
      console.log('Valid URL :' + url)
      urlArrays.push(url)
      res.json({ "original_url": url, "short_url": (urlArrays.length - 1) })
      console.log(urlArrays)
    }
  })
})

I would not use an array to store the urls because if you Stop the app to make changes and Start it again, a user that has already used the app to create a short url would more than likely get the wrong original url when supplying the short url. Why? Because when the app is restarted, you start off with an empty array of urls. Definitely look at using a database (like Mongo you should have already learned) or at least a flat file to store the data.

1 Like

Yeah I am aware it is not the best practice. I decided to use an array just to focus on the logic of the project itself. I’m now starting the Excercise Tracker where I will implement a Mongo DB.