Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to install and configure MEAN

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces the relevant knowledge of "how to install and configure MEAN". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

First define some small configuration libraries. File name: test/config/test_config.js

Module.exports = {url: 'http://localhost:8000/api/v1.0'}

The server runs on localhost 8000, which is ideal for initial testing. After that, if you change the location or port number of the product system, you can simply modify the file. In order to test well, you should first establish a good test environment, which can be guaranteed by the following code. First, connect to the database.

File name: est/setup_tests.js.

Function connectDB (callback) {mongoClient.connect (dbConfig.testDBURL, function (err, db) {assert.equal (null, err); reader_test_db = db; console.log ("Connected correctly to server"); callback (0);};}

The next step, drop user collection, does this to understand the state of the database.

Function dropUserCollection (callback) {console.log ("dropUserCollection"); user = reader_test_db.collection ('user'); if (undefined! = user) {user.drop (function (err, reply) {console.log (' user collection dropped'); callback (0);});} else {callback (0) }}

Next step, drop user feed entry collection.

Function dropUserFeedEntryCollection (callback) {console.log ("dropUserFeedEntryCollection"); user_feed_entry = reader_test_db.collection ('user_feed_entry'); if (undefined! = user_feed_entry) {user_feed_entry.drop (function (err, reply) {console.log (' user_feed_entry collection dropped'); callback (0);});} else {callback (0) }}

Next, connect to Stormpath, and then delete all users in the test application.

Function getApplication (callback) {console.log ("getApplication"); client.getApplications ({name: SP_APP_NAME}, function (err, applications) {console.log (applications); if (err) {log ("Error in getApplications"); throw err;} app = applications.items [0]; callback (0);}) }, function deleteTestAccounts (callback) {app.getAccounts ({email: TU_EMAIL_REGEX}, function (err, accounts) {if (err) throw err; accounts.items.forEach (function deleteAccount (account) {account.delete (function deleteError (err) {if (err) throw err;}); callback (0);});}

Next, shut down the database.

Function closeDB (callback) {reader_test_db.close ();}

Finally, async.series is called to ensure that all functions run in order.

Async.series ([connectDB, dropUserCollection, dropUserFeedEntryCollection, dropUserFeedEntryCollection, getApplication, deleteTestAccounts, closeDB])

Frisby is established at an early stage, and it will be used here to define test cases, as follows:

File name: test/createaccountserror_spec.js

TU1_FN = "Test"; TU1_LN = "User1"; TU1_EMAIL = "testuser1@example.com"; TU1_PW = "testUser123"; TU_EMAIL_REGEX = 'testuser*';SP_APP_NAME =' Reader Test';var frisby = require ('frisby'); var tc = require ('. / config/test_config')

The following code will start with enroll route. This use case intentionally drops the first name field, so it gets a return of 1 400 and 1 JSON error (showing that the first name is not defined). Here's toss that frisby:

Frisby.create ('POST missing firstName') .post (tc.url + / user/enroll', {' lastName': TU1_LN, 'email': TU1_EMAIL,' password': TU1_PW}). ExpectHeader ('Content-Type',' application/json; charset=utf-8'). ExpectJSON ({'error':' Undefined First Name'}). Toss ()

The following use case will test that it does not contain lowercase letters, which will also cause Stormpath to return an error and a status of 400.

An invalid email address will be tested below. Therefore, it is expected that the @ flag is not found, and the domain name is missing for the emali address, and you will also get a status of 1400.

File name: test/createaccountsspec.js

Frisby.create ('POST invalid email address') .post (tc.url +' / user/enroll', {'firstName': TU1_FN,' lastName': TU1_LN, 'email': "invalid.email",' password': 'testUser'}). ExpectHeader (' Content-Type', 'application/json; charset=utf-8'). ExpectJSONTypes ({' error': String}). Toss ()

Let's take a look at some examples that can be run, starting with defining three users.

File name: test/createaccountsspec.js

TEST_USERS = [{'fn':' Test', 'ln':' User1', 'email':' testuser1@example.com', 'pwd':' testUser123'}, {'fn':' Test', 'ln':' User2', 'email':' testuser2@example.com', 'pwd':' testUser123'} {'fn':' Test', 'ln':' User3', 'email':' testuser3@example.com', 'pwd':' testUser123'}] SP_APP_NAME = 'Reader Test' Var frisby = require ('frisby'); var tc = require ('. / config/test_config')

The following use case will send an array of three users defined above, and of course expect a 201 status that represents success. The returned JSON document displays the established user object, so you can check whether the test data matches or not.

TEST_USERS.forEach (function createUser (user, index, array) {frisby.create ('POST enroll user' + user.email). Post (tc.url +'/ user/enroll', {'firstName': user.fn,' lastName': user.ln, 'email': user.email,' password': user.pwd}) .accountStatus ('Content-Type') 'application/json Charset=utf-8') .accountJSON ({'firstName': user.fn,' lastName': user.ln, 'email': user.email}) .toss ()})

The next step is to test the duplicate user. The following example verifies that the email address registered by this user is already in use.

Frisby.create ('POST enroll duplicate user') .post (tc.url +'/ user/enroll', {'firstName': TEST_USERS [0] .fn,' lastName': TEST_USERS [0] .ln, 'email': TEST_USERS [0] .email,' password': TEST_USERS [0] .pwd}). ExpectHeader ('Content-Type',' application/json Charset=utf-8'). ExpectJSON ({'error':' Account with that email already exists. Please choose another email.'}) .toss ()

An important problem here is that there is no way to know which API key Stormpath will return first. Therefore, you need to create a dynamic file here. You can then use this pair file to validate the test case, the user authentication component.

File name: / tmp/readerTestCreds.js

TEST_USERS = [{"_ id": "54ad6c3ae764de42070b27b1", "email": "testuser1@example.com", "firstName": "Test", "lastName": "User1", "sp_api_key_id": "," sp_api_key_secret ":"}, {"_ id": "54ad6c3be764de42070b27b2", "email": "testuser2@example.com", "firstName": "Test", "lastName": "User2" "sp_api_key_id": "," sp_api_key_secret ":"}] Module.exports = TEST_USERS

To create the temporary file above, you need to connect to MongoDB to retrieve user information. The code is as follows:

File name: tests/writeCreds.js

TU_EMAIL_REGEX = new RegExp ('^ testuser*'); SP_APP_NAME = 'Reader Test';TEST_CREDS_TMP_FILE =' / tmp/readerTestCreds.js';var async = require ('async'); var dbConfig = require ('. / config/db.js'); var mongodb = require ('mongodb'); assert = require (' assert'); var mongoClient = mongodb.MongoClientvar reader_test_db = null;var users_array = null Function connectDB (callback) {mongoClient.connect (dbConfig.testDBURL, function (err, db) {assert.equal (null, err); reader_test_db = db; callback (null);} function lookupUserKeys (callback) {console.log ("lookupUserKeys"); user_coll = reader_test_db.collection ('user') User_coll.find ({email: TU_EMAIL_REGEX}) .toArray (function (err, users) {users_array = users; callback (null);} function writeCreds (callback) {var fs = require ('fs'); fs.writeFileSync (TEST_CREDS_TMP_FILE,' TEST_USERS ='); fs.appendFileSync (TEST_CREDS_TMP_FILE, JSON.stringify (users_array)) Fs.appendFileSync (TEST_CREDS_TMP_FILE,'; module.exports = TEST_USERS;'); callback (0);} function closeDB (callback) {reader_test_db.close ();} async.series ([connectDB, lookupUserKeys, writeCreds, closeDB])

Looking at the following code, the temporary file created above will be used on the first line. At the same time, multiple feeds are established, such as Dilbert and the Eater Blog.

File name: tests/feed_spec.js

TEST_USERS = require ('/ tmp/readerTestCreds.js'); var frisby = require ('frisby'); var tc = require ('. / config/test_config'); var async = require ('async'); var dbConfig = require ('. / config/db.js'); var dilbertFeedURL = 'http://feeds.feedburner.com/DilbertDailyStrip';var nycEaterFeedURL =' http://feeds.feedburner.com/eater/nyc';

First of all, some users will be established, of course, they do not subscribe to any feeds. The following code tests the subscription for feeds. Note that authentication is also required here, by using .auth and Stormpath API keys.

Function addEmptyFeedListTest (callback) {var user = TEST_USERS [0]; frisby.create ('GET empty feed list for user' + user.email) .get (tc.url +'/ feeds') .auth (user.sp_api_key_id, user.sp_api_key_secret) .returtStatus (2000.returtHeader ('Content-Type',' application/json) Charset=utf-8') .accountJSON ({feeds: []}) .toss () callback (null);}

The following use case will subscribe to Dilbert feed for the first test user.

This use case will attempt to repeat subscriptions for the user feed.

Function subDuplicateFeed (callback) {var user = TEST_USERS [0]; frisby.create ('PUT Add duplicate feed sub for user' + user.email) .put (tc.url +'/ feeds/subscribe', {'feedURL': dilbertFeedURL}) .auth (user.sp_api_key_id, user.sp_api_key_secret) .returtStatus (201) .returtHeader (' Content-Type', 'application/json) Charset=utf-8') .accountJSONLength ('user.subs', 1) .toss () callback (null);}

Next, you will add a new feed for the test user, and the result should be that the user has already subscribed to two feed.

Function subSecondFeed (callback) {var user = TEST_USERS [0]; frisby.create ('PUT Add second feed sub for user' + user.email) .put (tc.url +'/ feeds/subscribe', {'feedURL': nycEaterFeedURL}) .auth (user.sp_api_key_id, user.sp_api_key_secret) .returtStatus (201) .returtHeader (' Content-Type', 'application/json) Charset=utf-8') .accountJSONLength ('user.subs', 2) .toss () callback (null);}

Next, the second test user will be used to subscribe to 1 feed.

Function subOneFeedSecondUser (callback) {var user = TEST_USERS [1]; frisby.create ('PUT Add one feed sub for second user' + user.email) .put (tc.url +'/ feeds/subscribe', {'feedURL': nycEaterFeedURL}) .auth (user.sp_api_key_id, user.sp_api_key_secret) .returtStatus (201) .returtHeader (' Content-Type', 'application/json) Charset=utf-8') .accountJSONLength ('user.subs', 1) .toss () callback (null);} async.series ([addEmptyFeedListTest, subOneFeed, subDuplicateFeed, subSecondFeed, subOneFeedSecondUser])

# # REST API

Before you start writing REST API code, you first need to define some utility libraries. First, the requirements define how the application connects to the database. Writing this information to a separate file allows the application the flexibility to add a new database, URL, in response to the development or production system.

File name: config/db.js

If you expect to open database validation, you need to store the information in a file, as shown in the following code. This file should not be placed under source control for a number of reasons.

File name: config/security.js

Module.exports = {stormpath_secret_key: 'YOUR STORMPATH APPLICATION KEY';}

Stormpath API and Secret keys should be saved to the properties file, as shown in the following code, which colleagues also need to pay close attention to.

File name: config/stormpath_apikey.properties

ApiKey.id = YOUR STORMPATH API KEY IDapiKey.secret = YOUR STORMPATH API KEY SECRET

# # Overview of Express.js

An application (APP) is created in Express.js. The application listens on the established port to respond to HTTP requests. When requests pour in, they are transferred to a middleware chain. Each link in the middleware chain is given a request and a response object to store the results. There are two types of link, either working or passing to the next link. The new middleware will be added here through app.use (). The main middleware, called "router", listens to the URL and passes the URL/ action to a specified handler. # # Building an Application

Now start to focus on the application code, which is very small given that you can embed processors for different routes in separate files.

File name: server.js

Middleware is defined at the end of the chain to handle bad URLs.

The application will now listen on port 8000.

Print the message to the user in the console.

Console.log ('Magic happens on port' + port); exports = module.exports = app

# # defining Mongoose data Model

Mongoose is used here to map objects on Node.js to MongoDB documents. As mentioned above, four collections will be created here:

Feed collection .

Feed entry collection .

User collection .

User feed-entry-mapping collection .

Next, you will define the schema for the four collections. First, start with user schema. Note that data can also be formatted here, such as converting letters to lowercase and using trim to eliminate leading / final spaces.

File name: app/routes.js

Var userSchema = new mongoose.Schema ({active: Boolean, email: {type: String, trim: true, lowercase: true}, firstName: {type: String, trim: true}, lastName: {type: String, trim: true}, sp_api_key_id: {type: String, trim: true}, sp_api_key_secret: {type: String, trim: true}, subs: {type: [mongoose.Schema.Types.ObjectId] Default: []}, created: {type: Date, default: Date.now}, lastLogin: {type: Date, default: Date.now},}, {collection: 'user'})

The following code tells Mongoose which indexes are needed. When the index does not exist in the MongoDB database, Mongoose will be responsible for building the index. The uniqueness constraint guarantee will eliminate the possibility of repetition. "email: 1" maintains the address in ascending order, while "email:-1" is in descending order.

Repeat this step on the other three collections.

Var UserModel = mongoose.model ('User', userSchema) Var feedSchema = new mongoose.Schema ({feedURL: {type: String, trim:true}, link: {type: String, trim:true}, description: {type: String, trim:true}, state: {type: String, trim:true, lowercase:true, default: 'new'}, createdDate: {type: Date, default: Date.now}, modifiedDate: {type: Date, default: Date.now},}, {collection: feed'}) FeedSchema.index ({feedURL: 1}, {unique:true}); feedSchema.index ({link: 1}, {unique:true, sparse:true}); var FeedModel = mongoose.model ('Feed', feedSchema) Var feedEntrySchema = new mongoose.Schema ({description: {type: String, trim:true}, title: {type: String, trim:true}, summary: {type: String, trim:true}, entryID: {type: String, trim:true}, publishedDate: {type: Date}, link: {type: String, trim:true}, feedID: {type: mongoose.Schema.Types.ObjectId}, state: {type: String, trim:true, lowercase:true Default: 'new'}, created: {type: Date, default: Date.now},}, {collection:' feedEntry'}) FeedEntrySchema.index ({entryID: 1}); feedEntrySchema.index ({feedID: 1}); var FeedEntryModel = mongoose.model ('FeedEntry', feedEntrySchema); var userFeedEntrySchema = new mongoose.Schema ({userID: {type: mongoose.Schema.Types.ObjectId}, feedEntryID: {type: mongoose.Schema.Types.ObjectId}, feedID: {type: mongoose.Schema.Types.ObjectId}, read: {type: Boolean, default: false},}, {collection:' userFeedEntry'})

The following is a composite index instance, with each index maintained in ascending order.

UserFeedEntrySchema.index ({userID: 1, feedID: 1, feedEntryID: 1, read: 1}); var UserFeedEntryModel = mongoose.model ('UserFeedEntry', userFeedEntrySchema)

Each request for GET, POST, PUT, and DELETE needs to have the correct content type, that is, application/json. Then the next link will be called.

The next step is to define a processor for each URL/verb. All the code is attached in the Resources section, and the following is just a code snippet. In this code, the convenience brought by Stormpath is at a glance. In addition, / api/v1.0 is defined here, and for example, the client can call / api/v1.0/user/enroll. If you use / api/v2.0,/api/v2.0, it can be used, of course, backward compatibility.

To start the server and run the tests, there are several steps to follow.

Make sure the MongoDB instance is running, mongod.

Install the Node library, npm install.

Open the REST API server, node server.js.

Run the test case: node setup_tests.js;jasmine-node create_accounts_error_spec.js;jasmine-node create_accounts_spec.js;node write_creds.js;jasmine-node feed_spec.js.

This is the end of the content of "how to install MEAN configuration". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report