From db5854ecf6900af4ce952b4d2bd536ea75aa9671 Mon Sep 17 00:00:00 2001 From: Ilenia <26656284+ilenia-magoni@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:11:25 +0200 Subject: [PATCH] chore(curriculum): add url shortener lab (#56050) Co-authored-by: Tom <20648924+moT01@users.noreply.github.com> --- client/i18n/locales/english/intro.json | 5 +- .../lab-url-shortener-microservice/index.md | 9 ++ .../lab-url-shortener-microservice/meta.json | 10 ++ .../bd7158d8c443edefaeb5bd0e.md | 107 ++++++++++++++++++ curriculum/test/utils/mongo-ids.js | 1 + 5 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 client/src/pages/learn/front-end-development/lab-url-shortener-microservice/index.md create mode 100644 curriculum/challenges/_meta/lab-url-shortener-microservice/meta.json create mode 100644 curriculum/challenges/english/25-front-end-development/lab-url-shortener-microservice/bd7158d8c443edefaeb5bd0e.md diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index e56d8677852..0e13002035c 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -2229,7 +2229,10 @@ "sykw": { "title": "372", "intro": [] }, "zzhp": { "title": "373", "intro": [] }, "nmve": { "title": "374", "intro": [] }, - "agky": { "title": "375", "intro": [] }, + "lab-url-shortener-microservice": { + "title": "Build a URL Shortener Microservice", + "intro": ["In this lab, you will build a URL Shortener Microservice"] + }, "lab-exercise-tracker": { "title": "Build an Exercise Tracker", "intro": ["In this lab, you will build an exercise tracker"] diff --git a/client/src/pages/learn/front-end-development/lab-url-shortener-microservice/index.md b/client/src/pages/learn/front-end-development/lab-url-shortener-microservice/index.md new file mode 100644 index 00000000000..aaf7c1c28f7 --- /dev/null +++ b/client/src/pages/learn/front-end-development/lab-url-shortener-microservice/index.md @@ -0,0 +1,9 @@ +--- +title: Introduction to the Build a URL Shortener Microservice +block: lab-url-shortener-microservice +superBlock: front-end-development +--- + +## Introduction to the Build a URL Shortener Microservice + +In this lab you will build a URL Shortener Microservice diff --git a/curriculum/challenges/_meta/lab-url-shortener-microservice/meta.json b/curriculum/challenges/_meta/lab-url-shortener-microservice/meta.json new file mode 100644 index 00000000000..2b4c897bee7 --- /dev/null +++ b/curriculum/challenges/_meta/lab-url-shortener-microservice/meta.json @@ -0,0 +1,10 @@ +{ + "name": "Build a URL Shortener Microservice", + "isUpcomingChange": true, + "dashedName": "lab-url-shortener-microservice", + "order": 375, + "superBlock": "front-end-development", + "challengeOrder": [{ "id": "bd7158d8c443edefaeb5bd0e", "title": "Build a URL Shortener Microservice" }], + "helpCategory": "Backend Development", + "blockType": "lab" + } diff --git a/curriculum/challenges/english/25-front-end-development/lab-url-shortener-microservice/bd7158d8c443edefaeb5bd0e.md b/curriculum/challenges/english/25-front-end-development/lab-url-shortener-microservice/bd7158d8c443edefaeb5bd0e.md new file mode 100644 index 00000000000..0fbf80a0bfe --- /dev/null +++ b/curriculum/challenges/english/25-front-end-development/lab-url-shortener-microservice/bd7158d8c443edefaeb5bd0e.md @@ -0,0 +1,107 @@ +--- +id: bd7158d8c443edefaeb5bd0e +title: URL Shortener Microservice +challengeType: 4 +dashedName: url-shortener-microservice +--- + +# --description-- + +Build a full stack JavaScript app that is functionally similar to this: https://url-shortener-microservice.freecodecamp.rocks. Working on this project will involve you writing your code using one of the following methods: + +- Clone this GitHub repo and complete your project locally. +- Use our Gitpod starter project to complete your project. +- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. + +# --instructions-- + +**HINT:** Do not forget to use a body parsing middleware to handle the POST requests. Also, you can use the function `dns.lookup(host, cb)` from the `dns` core module to verify a submitted URL. + +# --hints-- + +You should provide your own project, not the example URL. + +```js +(getUserInput) => { + assert( + !/.*\/url-shortener-microservice\.freecodecamp\.rocks/.test( + getUserInput('url') + ) + ); +}; +``` + +You can POST a URL to `/api/shorturl` and get a JSON response with `original_url` and `short_url` properties. Here's an example: `{ original_url : 'https://freeCodeCamp.org', short_url : 1}` + +```js +async (getUserInput) => { + const url = getUserInput('url'); + const urlVariable = Date.now(); + const fullUrl = `${url}/?v=${urlVariable}` + const res = await fetch(url + '/api/shorturl', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `url=${fullUrl}` + }); + if (res.ok) { + const { short_url, original_url } = await res.json(); + assert.isNotNull(short_url); + assert.strictEqual(original_url, `${url}/?v=${urlVariable}`); + } else { + throw new Error(`${res.status} ${res.statusText}`); + } +}; +``` + +When you visit `/api/shorturl/`, you will be redirected to the original URL. + +```js +async (getUserInput) => { + const url = getUserInput('url'); + const urlVariable = Date.now(); + const fullUrl = `${url}/?v=${urlVariable}` + let shortenedUrlVariable; + const postResponse = await fetch(url + '/api/shorturl', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `url=${fullUrl}` + }); + if (postResponse.ok) { + const { short_url } = await postResponse.json(); + shortenedUrlVariable = short_url; + } else { + throw new Error(`${postResponse.status} ${postResponse.statusText}`); + } + const getResponse = await fetch( + url + '/api/shorturl/' + shortenedUrlVariable + ); + if (getResponse) { + const { redirected, url } = getResponse; + assert.isTrue(redirected); + assert.strictEqual(url,fullUrl); + } else { + throw new Error(`${getResponse.status} ${getResponse.statusText}`); + } +}; +``` + +If you pass an invalid URL that doesn't follow the valid `http://www.example.com` format, the JSON response will contain `{ error: 'invalid url' }` + +```js +async (getUserInput) => { + const url = getUserInput('url'); + const res = await fetch(url + '/api/shorturl', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `url=ftp:/john-doe.invalidTLD` + }); + if (res.ok) { + const { error } = await res.json(); + assert.isNotNull(error); + assert.strictEqual(error.toLowerCase(), 'invalid url'); + } else { + throw new Error(`${res.status} ${res.statusText}`); + } +}; +``` + diff --git a/curriculum/test/utils/mongo-ids.js b/curriculum/test/utils/mongo-ids.js index 00528e0f62b..572aa4fbfa8 100644 --- a/curriculum/test/utils/mongo-ids.js +++ b/curriculum/test/utils/mongo-ids.js @@ -14,6 +14,7 @@ const duplicatedProjectIds = [ '56533eb9ac21ba0edf2244e2', 'aff0395860f5d3034dc0bfc9', 'aa2e6f85cab2ab736c9a9b24', + 'bd7158d8c443edefaeb5bd0e', '5a8b073d06fa14fcfde687aa' ];