├── .gitignore ├── Dockerfile ├── .dockerignore ├── package.json ├── README.md ├── app-controller.js ├── app.js ├── oas.json ├── index.html └── app-test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | solar-system.png 3 | .nyc_output 4 | .talismanrc 5 | coverage 6 | test-results.xml -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine3.17 2 | 3 | WORKDIR /usr/app 4 | 5 | COPY package*.json /usr/app/ 6 | 7 | RUN npm install 8 | 9 | COPY . . 10 | 11 | ENV MONGO_URI=uriPlaceholder 12 | ENV MONGO_USERNAME=usernamePlaceholder 13 | ENV MONGO_PASSWORD=passwordPlaceholder 14 | 15 | EXPOSE 3000 16 | 17 | CMD [ "npm", "start" ] -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------------* 2 | # This will prevent your local modules and debug logs from being copied onto your 3 | # Docker image and possibly overwriting modules installed within your image. 4 | # ---------------------------------------------------------------------------------* 5 | node_modules 6 | npm-debug.log 7 | # ignore .git and .cache folders 8 | .git 9 | .cache 10 | # ignore all markdown files (md) beside all README*.md other than README-secret.md 11 | *.md 12 | !README*.md 13 | README-secret.md 14 | # github related files 15 | .github/ 16 | # nodejs releated files 17 | node_modules 18 | solar-system.png 19 | .nyc_output 20 | .talismanrc 21 | coverage 22 | test-results.xml 23 | #reports 24 | reports* 25 | zap* 26 | dependency* 27 | jenkins* 28 | trivy-image* 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Solar System", 3 | "version": "6.7.6", 4 | "author": "Siddharth Barahalikar ", 5 | "homepage": "https://www.linkedin.com/in/barahalikar-siddharth/", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "node app.js", 9 | "test": "mocha app-test.js --timeout 10000 --reporter mocha-junit-reporter --exit", 10 | "coverage": "nyc --reporter cobertura --reporter lcov --reporter text --reporter json-summary mocha app-test.js --timeout 10000 --exit" 11 | }, 12 | "nyc": { 13 | "check-coverage": true, 14 | "lines": 90 15 | }, 16 | "dependencies": { 17 | "cors": "^2.8.5", 18 | "express": "^4.18.2", 19 | "mocha-junit-reporter": "^2.2.1", 20 | "mongoose": "5.13.20", 21 | "nyc": "^15.1.0", 22 | "serverless-http": "^3.2.0" 23 | }, 24 | "devDependencies": { 25 | "chai": "*", 26 | "chai-http": "*", 27 | "mocha": "*" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solar System NodeJS Application 2 | 3 | A simple HTML+MongoDB+NodeJS project to display Solar System and it's planets. 4 | 5 | --- 6 | ## Requirements 7 | 8 | For development, you will only need Node.js and NPM installed in your environement. 9 | 10 | ### Node 11 | - #### Node installation on Windows 12 | 13 | Just go on [official Node.js website](https://nodejs.org/) and download the installer. 14 | Also, be sure to have `git` available in your PATH, `npm` might need it (You can find git [here](https://git-scm.com/)). 15 | 16 | - #### Node installation on Ubuntu 17 | 18 | You can install nodejs and npm easily with apt install, just run the following commands. 19 | 20 | $ sudo apt install nodejs 21 | $ sudo apt install npm 22 | 23 | - #### Other Operating Systems 24 | You can find more information about the installation on the [official Node.js website](https://nodejs.org/) and the [official NPM website](https://npmjs.org/). 25 | 26 | If the installation was successful, you should be able to run the following command. 27 | 28 | $ node --version 29 | v8.11.3 30 | 31 | $ npm --version 32 | 6.1.0 33 | 34 | --- 35 | ## Install Dependencies from `package.json` 36 | $ npm install 37 | 38 | ## Run Unit Testing 39 | $ npm test 40 | 41 | ## Run Code Coverage 42 | $ npm run coverage 43 | 44 | ## Run Application 45 | $ npm start 46 | 47 | ## Access Application on Browser 48 | http://localhost:3000/ 49 | 50 | -------------------------------------------------------------------------------- /app-controller.js: -------------------------------------------------------------------------------- 1 | console.log('We are inside client.js'); 2 | 3 | /* on page load */ 4 | window.onload = function() { 5 | const planet_id = document.getElementById("planetID").value 6 | console.log("onLoad - Request Planet ID - " + planet_id) 7 | 8 | fetch("/os", { 9 | method: "GET" 10 | }) 11 | .then(function(res) { 12 | if (res.ok) { 13 | return res.json(); 14 | } 15 | thrownewError('Request failed'); 16 | }).catch(function(error) { 17 | console.log(error); 18 | }) 19 | .then(function(data) { 20 | document.getElementById('hostname').innerHTML = `Pod - ${data.os} ` 21 | // document.getElementById('environment').innerHTML = ` Env - ${data.env} ` 22 | }); 23 | }; 24 | 25 | 26 | 27 | const btn = document.getElementById('submit'); 28 | if (btn) { 29 | btn.addEventListener('click', func); 30 | } 31 | 32 | function func() { 33 | const planet_id = document.getElementById("planetID").value 34 | console.log("onClick Submit - Request Planet ID - " + planet_id) 35 | 36 | fetch("/planet", { 37 | method: "POST", 38 | body: JSON.stringify({ 39 | id: document.getElementById("planetID").value 40 | }), 41 | headers: { 42 | "Content-type": "application/json; charset=UTF-8" 43 | } 44 | }) 45 | .then(function(res2) { 46 | if (res2.ok) { 47 | return res2.json(); 48 | } 49 | thrownewError('Request failed.'); 50 | }).catch(function(error) { 51 | alert("Ooops, We have 8 planets.\nSelect a number from 0 - 8") 52 | console.log(error); 53 | }) 54 | .then(function(data) { 55 | document.getElementById('planetName').innerHTML = ` ${data.name} ` 56 | 57 | const element = document.getElementById("planetImage"); 58 | const image = ` ${data.image} ` 59 | element.style.backgroundImage = "url("+image+")" 60 | 61 | const planet_description = ` ${data.description} ` 62 | document.getElementById('planetDescription').innerHTML = planet_description.replace(/(.{80})/g, "$1
"); 63 | 64 | 65 | }); 66 | 67 | } -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs') 3 | const express = require('express'); 4 | const OS = require('os'); 5 | const bodyParser = require('body-parser'); 6 | const mongoose = require("mongoose"); 7 | const app = express(); 8 | const cors = require('cors') 9 | const serverless = require('serverless-http') 10 | 11 | 12 | app.use(bodyParser.json()); 13 | app.use(express.static(path.join(__dirname, '/'))); 14 | app.use(cors()) 15 | 16 | mongoose.connect(process.env.MONGO_URI, { 17 | user: process.env.MONGO_USERNAME, 18 | pass: process.env.MONGO_PASSWORD, 19 | useNewUrlParser: true, 20 | useUnifiedTopology: true 21 | }, function(err) { 22 | if (err) { 23 | console.log("error!! " + err) 24 | } else { 25 | // console.log("MongoDB Connection Successful") 26 | } 27 | }) 28 | 29 | var Schema = mongoose.Schema; 30 | 31 | var dataSchema = new Schema({ 32 | name: String, 33 | id: Number, 34 | description: String, 35 | image: String, 36 | velocity: String, 37 | distance: String 38 | }); 39 | var planetModel = mongoose.model('planets', dataSchema); 40 | 41 | 42 | 43 | app.post('/planet', function(req, res) { 44 | // console.log("Received Planet ID " + req.body.id) 45 | planetModel.findOne({ 46 | id: req.body.id 47 | }, function(err, planetData) { 48 | if (err) { 49 | alert("Ooops, We only have 9 planets and a sun. Select a number from 0 - 9") 50 | res.send("Error in Planet Data") 51 | } else { 52 | res.send(planetData); 53 | } 54 | }) 55 | }) 56 | 57 | app.get('/', async (req, res) => { 58 | res.sendFile(path.join(__dirname, '/', 'index.html')); 59 | }); 60 | 61 | app.get('/api-docs', (req, res) => { 62 | fs.readFile('oas.json', 'utf8', (err, data) => { 63 | if (err) { 64 | console.error('Error reading file:', err); 65 | res.status(500).send('Error reading file'); 66 | } else { 67 | res.json(JSON.parse(data)); 68 | } 69 | }); 70 | }); 71 | 72 | app.get('/os', function(req, res) { 73 | res.setHeader('Content-Type', 'application/json'); 74 | res.send({ 75 | "os": OS.hostname(), 76 | "env": process.env.NODE_ENV 77 | }); 78 | }) 79 | 80 | app.get('/live', function(req, res) { 81 | res.setHeader('Content-Type', 'application/json'); 82 | res.send({ 83 | "status": "live" 84 | }); 85 | }) 86 | 87 | app.get('/ready', function(req, res) { 88 | res.setHeader('Content-Type', 'application/json'); 89 | res.send({ 90 | "status": "ready" 91 | }); 92 | }) 93 | 94 | app.listen(3000, () => { console.log("Server successfully running on port - " +3000); }) 95 | module.exports = app; 96 | 97 | //module.exports.handler = serverless(app) 98 | -------------------------------------------------------------------------------- /oas.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.0", 3 | "info": { 4 | "title": "Solar System API", 5 | "version": "1.0" 6 | }, 7 | "paths": { 8 | "/": { 9 | "get": { 10 | "responses": { 11 | "200": { 12 | "description": "", 13 | "content": { 14 | "text/plain": { 15 | "schema": { 16 | "example": "Example", 17 | "type": "string" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | } 24 | }, 25 | "/live": { 26 | "get": { 27 | "responses": { 28 | "200": { 29 | "description": "", 30 | "content": { 31 | "text/plain": { 32 | "schema": { 33 | "example": "Live", 34 | "type": "string" 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | }, 42 | "/os": { 43 | "get": { 44 | "responses": { 45 | "200": { 46 | "description": "", 47 | "content": { 48 | "application/json": { 49 | "schema": { 50 | "example": { 51 | "strict": true, 52 | "value": { 53 | "os": "f7ed9952e2ed" 54 | } 55 | }, 56 | "type": "object" 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | }, 64 | "/planet": { 65 | "post": { 66 | "requestBody": { 67 | "content": { 68 | "application/json": { 69 | "schema": { 70 | "example": { 71 | "strict": true, 72 | "value": { 73 | "id": "3" 74 | } 75 | }, 76 | "type": "object" 77 | } 78 | } 79 | } 80 | }, 81 | "responses": { 82 | "200": { 83 | "description": "", 84 | "content": { 85 | "application/json": { 86 | "schema": { 87 | "example": { 88 | "strict": true, 89 | "value": { 90 | "_id": "64de122465ba6ca132e2d046", 91 | "id": 3, 92 | "name": "Earth", 93 | "image": "https://gitlab.com/sidd-harth/solar-system/-/raw/main/images/earth.png", 94 | "velocity": "29", 95 | "distance": "149", 96 | "description": "Earth is the third planet from the Sun and is the largest of the terrestrial planets. The Earth is the only planet in our solar system not to be named after a Greek or Roman deity. The Earth was formed approximately 4.54 billion years ago and is the only known planet to support life. Earth has one Moon, the largest moon of any rocky planet in the Solar System. Earth also has more than 20 known co-orbitals, including the asteroids 3753 Cruithne and 469219 Kamoʻoalewa, and the occasional temporary satellite, like 2020 CD3; however, since they do not permanently orbit Earth, they are not considered moons. " 97 | } 98 | }, 99 | "type": "object" 100 | } 101 | } 102 | } 103 | } 104 | } 105 | } 106 | }, 107 | "/ready": { 108 | "get": { 109 | "responses": { 110 | "200": { 111 | "description": "", 112 | "content": { 113 | "text/plain": { 114 | "schema": { 115 | "example": "Ready", 116 | "type": "string" 117 | } 118 | } 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Solar System - Sid 23 | 24 | 48 | 49 | 50 | 51 |
52 |
53 | 54 | 67 | 68 | 69 |
70 |
71 | 81 |
82 | 89 |
90 |
91 |

Solar System

92 |
93 |
94 |

Solar system consists of our star, the Sun, and everything bound to it by gravity –
the planets Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune;
dwarf planets such as Pluto; dozens of moons; and millions
of asteroids, comets, and meteoroids.

95 |
96 |
97 |
98 |

Solar System Pod Name

99 | 100 | 101 |
102 |
103 |
104 |
105 | 106 | 107 | -------------------------------------------------------------------------------- /app-test.js: -------------------------------------------------------------------------------- 1 | let mongoose = require("mongoose"); 2 | let server = require("./app"); 3 | let chai = require("chai"); 4 | let chaiHttp = require("chai-http"); 5 | 6 | 7 | // Assertion 8 | chai.should(); 9 | chai.use(chaiHttp); 10 | 11 | describe('Planets API Suite', () => { 12 | 13 | describe('Fetching Planet Details', () => { 14 | it('it should fetch a planet named Mercury', (done) => { 15 | let payload = { 16 | id: 1 17 | } 18 | chai.request(server) 19 | .post('/planet') 20 | .send(payload) 21 | .end((err, res) => { 22 | res.should.have.status(200); 23 | res.body.should.have.property('id').eql(1); 24 | res.body.should.have.property('name').eql('Mercury'); 25 | done(); 26 | }); 27 | }); 28 | 29 | it('it should fetch a planet named Venus', (done) => { 30 | let payload = { 31 | id: 2 32 | } 33 | chai.request(server) 34 | .post('/planet') 35 | .send(payload) 36 | .end((err, res) => { 37 | res.should.have.status(200); 38 | res.body.should.have.property('id').eql(2); 39 | res.body.should.have.property('name').eql('Venus'); 40 | done(); 41 | }); 42 | }); 43 | 44 | it('it should fetch a planet named Earth', (done) => { 45 | let payload = { 46 | id: 3 47 | } 48 | chai.request(server) 49 | .post('/planet') 50 | .send(payload) 51 | .end((err, res) => { 52 | res.should.have.status(200); 53 | res.body.should.have.property('id').eql(3); 54 | res.body.should.have.property('name').eql('Earth'); 55 | done(); 56 | }); 57 | }); 58 | it('it should fetch a planet named Mars', (done) => { 59 | let payload = { 60 | id: 4 61 | } 62 | chai.request(server) 63 | .post('/planet') 64 | .send(payload) 65 | .end((err, res) => { 66 | res.should.have.status(200); 67 | res.body.should.have.property('id').eql(4); 68 | res.body.should.have.property('name').eql('Mars'); 69 | done(); 70 | }); 71 | }); 72 | 73 | it('it should fetch a planet named Jupiter', (done) => { 74 | let payload = { 75 | id: 5 76 | } 77 | chai.request(server) 78 | .post('/planet') 79 | .send(payload) 80 | .end((err, res) => { 81 | res.should.have.status(200); 82 | res.body.should.have.property('id').eql(5); 83 | res.body.should.have.property('name').eql('Jupiter'); 84 | done(); 85 | }); 86 | }); 87 | 88 | it('it should fetch a planet named Satrun', (done) => { 89 | let payload = { 90 | id: 6 91 | } 92 | chai.request(server) 93 | .post('/planet') 94 | .send(payload) 95 | .end((err, res) => { 96 | res.should.have.status(200); 97 | res.body.should.have.property('id').eql(6); 98 | res.body.should.have.property('name').eql('Saturn'); 99 | done(); 100 | }); 101 | }); 102 | 103 | it('it should fetch a planet named Uranus', (done) => { 104 | let payload = { 105 | id: 7 106 | } 107 | chai.request(server) 108 | .post('/planet') 109 | .send(payload) 110 | .end((err, res) => { 111 | res.should.have.status(200); 112 | res.body.should.have.property('id').eql(7); 113 | res.body.should.have.property('name').eql('Uranus'); 114 | done(); 115 | }); 116 | }); 117 | 118 | it('it should fetch a planet named Neptune', (done) => { 119 | let payload = { 120 | id: 8 121 | } 122 | chai.request(server) 123 | .post('/planet') 124 | .send(payload) 125 | .end((err, res) => { 126 | res.should.have.status(200); 127 | res.body.should.have.property('id').eql(8); 128 | res.body.should.have.property('name').eql('Neptune'); 129 | done(); 130 | }); 131 | }); 132 | 133 | // it('it should fetch a planet named Pluto', (done) => { 134 | // let payload = { 135 | // id: 9 136 | // } 137 | // chai.request(server) 138 | // .post('/planet') 139 | // .send(payload) 140 | // .end((err, res) => { 141 | // res.should.have.status(200); 142 | // res.body.should.have.property('id').eql(9); 143 | // res.body.should.have.property('name').eql('Sun'); 144 | // done(); 145 | // }); 146 | // }); 147 | 148 | 149 | }); 150 | }); 151 | 152 | //Use below test case to achieve coverage 153 | describe('Testing Other Endpoints', () => { 154 | 155 | describe('it should fetch OS Details', () => { 156 | it('it should fetch OS details', (done) => { 157 | chai.request(server) 158 | .get('/os') 159 | .end((err, res) => { 160 | res.should.have.status(200); 161 | done(); 162 | }); 163 | }); 164 | }); 165 | 166 | describe('it should fetch Live Status', () => { 167 | it('it checks Liveness endpoint', (done) => { 168 | chai.request(server) 169 | .get('/live') 170 | .end((err, res) => { 171 | res.should.have.status(200); 172 | res.body.should.have.property('status').eql('live'); 173 | done(); 174 | }); 175 | }); 176 | }); 177 | 178 | describe('it should fetch Ready Status', () => { 179 | it('it checks Readiness endpoint', (done) => { 180 | chai.request(server) 181 | .get('/ready') 182 | .end((err, res) => { 183 | res.should.have.status(200); 184 | res.body.should.have.property('status').eql('ready'); 185 | done(); 186 | }); 187 | }); 188 | }); 189 | 190 | }); --------------------------------------------------------------------------------