---
id: 587d824a367417b2b2512c44
title: 株価チェッカー
challengeType: 4
forumTopicId: 301572
dashedName: stock-price-checker
---
# --description--
と同様の機能を持つフルスタック JavaScript アプリを構築してください。
信頼できる株価 API の利用にはすべて API キーが必要になるため、ここでは回避策を用意しました。 を使用すれば、登録して自分のキーを取得しなくても最新の株価情報を得ることができます。
プロジェクトに取り組むにあたり、以下の方法のうち 1 つを用いてコードを記述します。
- [ GitHub リポジトリ](https://github.com/freeCodeCamp/boilerplate-project-stockchecker/)をクローンし、ローカル環境でプロジェクトを完了させる。
- [Replit 始動プロジェクト](https://replit.com/github/freeCodeCamp/boilerplate-project-stockchecker)を使用して、プロジェクトを完了させる。
- 使い慣れたサイトビルダーを使用してプロジェクトを完了させる。 必ず GitHub リポジトリのすべてのファイルを取り込む。
完了したら、プロジェクトの動作デモをどこか公開の場にホストしてください。 そして、`Solution Link` フィールドでデモへの URL を送信してください。 必要に応じて、`GitHub Link` フィールドでプロジェクトのソースコードへのリンクを送信してください。
# --instructions--
1. `NODE_ENV` を引用符なしの `test` に設定し、`DB` を MongoDB 接続文字列に設定します。
2. `routes/api.js` でプロジェクトを完成させるか、ハンドラー/コントローラーを作成します。
3. `server.js` にセキュリティ機能を追加します。
4. `tests/2_functional-tests.js` にすべての機能テストを作成します。
**注**: プライバシーに対する注意事項: 1 つの IP に対して 1 つの「いいね!」しか受け付けないという条件があるため、IP アドレスを保存する必要があります。 一般データ保護規則などのデータプライバシー関連の法令を遵守することが重要です。 ユーザーのデータを保存するための権限を取得するという方法もありますが、データを匿名化した方がはるかに簡単です。 このチャレンジでは、データベースに保存する前に必ず IP アドレスを匿名化してください。 その方法として、データをハッシュ化する、切り詰める、IP アドレスの一部を 0 にする、などが考えられます。
次のテストを `tests/2_functional-tests.js` に記述してください。
- 1 つの株式を表示: `/api/stock-prices/` への GET リクエスト
- 1 つの株式を表示して「いいね!」をクリック: `/api/stock-prices/` への GET リクエスト
- もう一度同じ株式を表示して「いいね!」をクリック: `/api/stock-prices/` への GET リクエスト
- 2 つの株式を表示: `/api/stock-prices/` への GET リクエスト
- 2 つの株式を表示して「いいね!」をクリック: `/api/stock-prices/` への GET リクエスト
# --hints--
サンプルの URL ではなく、自分で作成したプロジェクトを提供することができます。
```js
(getUserInput) => {
assert(
!/.*\/stock-price-checker\.freecodecamp\.rocks/.test(getUserInput('url'))
);
};
```
コンテンツセキュリティポリシーを設定して、自分のサーバーからのスクリプトや CSS の読み込みのみを許可するようにしてください。
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.isTrue(
parsed.headers['content-security-policy'].includes("script-src 'self'")
);
assert.isTrue(
parsed.headers['content-security-policy'].includes("style-src 'self'")
);
};
```
`GET` リクエストを `/api/stock-prices` に送信し、NASDAQ 株式表示記号を `stock` クエリパラメーターに渡すことができます。 返されるオブジェクトには、`stockData` というプロパティが含まれます。
```js
async (getUserInput) => {
const data = await fetch(
getUserInput('url') + '/api/stock-prices?stock=GOOG'
);
const parsed = await data.json();
assert.property(parsed, 'stockData');
};
```
`stockData` プロパティには、文字列としての `stock` 記号、数値としての `price`、数値としての `likes` が含まれています。
```js
async (getUserInput) => {
const data = await fetch(
getUserInput('url') + '/api/stock-prices?stock=GOOG'
);
const parsed = await data.json();
const ticker = parsed.stockData;
assert.typeOf(ticker.price, 'number');
assert.typeOf(ticker.likes, 'number');
assert.typeOf(ticker.stock, 'string');
};
```
また、`like` フィールドに `true` (ブール値) を渡すと、その株式の「いいね!」が増えます。 「いいね!」は、1 つの IP につき 1 回のみ受け付ける必要があります。
```js
```
2 つの株式を渡した場合、返される値は 2 つの株式に関する情報を持つ配列となります。 `likes` の代わりに、両方の `stockData` オブジェクトの `rel_likes` (両株式の「いいね!」の差) を表示します。
```js
async (getUserInput) => {
const data = await fetch(
getUserInput('url') + '/api/stock-prices?stock=GOOG&stock=MSFT'
);
const parsed = await data.json();
const ticker = parsed.stockData;
assert.typeOf(ticker, 'array');
assert.property(ticker[0], 'rel_likes');
assert.property(ticker[1], 'rel_likes');
};
```
5 種類の機能テストがすべて完了して、合格です。
```js
async (getUserInput) => {
const tests = await fetch(getUserInput('url') + '/_api/get-tests');
const parsed = await tests.json();
assert.isTrue(parsed.length >= 5);
parsed.forEach((test) => {
assert.equal(test.state, 'passed');
});
};
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```