freeCodeCamp/curriculum/challenges/chinese/05-apis-and-microservices/apis-and-microservices-proj.../exercise-tracker.md

7.9 KiB
Raw Blame History

id challengeType forumTopicId title
5a8b073d06fa14fcfde687aa 4 301505 运动跟踪器

Description

构建一个功能类似于 https://fuschia-custard.glitch.me/ 的 JavaScript 全栈应用。 在开发这个项目时,我们推荐你在 Glitch 上编码。编码完成之后,你可以把应用主页的链接复制到屏幕的输入框中,测试你的代码是否能通过项目需求。当然你也可以基于其他的平台来完成自己的项目,只要提供一个公开的主页便于我们测试就行。 参考示例:你可以通过 这个链接 访问在 Glitch 上的项目,或者从 GitHub 上 clone 这个仓库的代码。如果你使用 Glitch请记住将项目链接保存到妥当的地方。

Instructions

Tests

tests:
  - text: 提供独立的项目, 而不是例程 url.
    testString: "getUserInput => {
      const url = getUserInput('url');
      assert(!(new RegExp('.*/fuschia-custard\\.glitch\\.me\\.*')).test(getUserInput('url')));
    }
    "

  - text: 通过指定 `/api/exercise/new-user` 的 username 参数来创建用户, 并且返回一个具有 username 和 _id 的对象。
    testString: "async getUserInput => {
      const url = getUserInput('url');
      const res = await fetch(url + '/api/exercise/new-user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: `username=fcc_test_${Date.now()}`.substr(0, 29)
      });

      if (res.ok) {
        const { _id, username } = await res.json();
          assert.exists(_id);
          assert.exists(username);
      } else {
        throw new Error(`${res.status} ${res.statusText}`);
      }
    }
    "
  - text: 通过指定 `api/exercise/users` 的参数为创建用户时相同的信息,来获取到一个用户的数组。
    testString: "async getUserInput => {
      const url = getUserInput('url');
      const res = await fetch(url + '/api/exercise/users');

      if (res.ok) {
        const data = await res.json();
        assert.isArray(data);
      } else {
        throw new Error(`${res.status} ${res.statusText}`);
      }
    }
    "
  - text: 通过指定 `/api/exercise/add` 的 userId、description、duration 和 date可选参数, 去添加一条练习记录。 当没有传入 date 的时候,默认采用当前日期。 应用程序将返回添加了练习字段的用户对象。
    testString: "async getUserInput => {
      const url = getUserInput('url');
      const res = await fetch(url + '/api/exercise/new-user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: `username=fcc_test_${Date.now()}`.substr(0, 29)
      });

      if (res.ok) {
        const { _id, username } = await res.json();
        const expected = {
          username,
          description: 'test',
          duration: 60,
          _id,
          date: 'Mon Jan 01 1990'
        };

        const addRes = await fetch(url + '/api/exercise/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `userId=${_id}&description=${expected.description}&duration=${expected.duration}&date=1990-01-01`
        });
        if (addRes.ok) {
          const actual = await addRes.json();
          assert.deepEqual(actual, expected);
        } else {
          throw new Error(`${addRes.status} ${addRes.statusText}`);
        }
      } else {
        throw new Error(`${res.status} ${res.statusText}`);
      }
    }
    "
  - text: 通过指定 `/api/exercise/log` 的 userId 参数,可以获取任意用户的练习日志和总的练习次数。
    testString: "async getUserInput => {
      const url = getUserInput('url');
      const res = await fetch(url + '/api/exercise/new-user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: `username=fcc_test_${Date.now()}`.substr(0, 29)
      });

      if (res.ok) {
        const { _id, username } = await res.json();
        const expected = {
          username,
          description: 'test',
          duration: 60,
          _id,
          date: new Date().toDateString()
        };

        const addRes = await fetch(url + '/api/exercise/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `userId=${_id}&description=${expected.description}&duration=${expected.duration}`
        });
        if (addRes.ok) {
          const logRes = await fetch(url + `/api/exercise/log?userId=${_id}`);
          if (logRes.ok) {
            const { log } = await logRes.json();
            assert.isArray(log);
            assert.equal(1, log.length);
          } else {
            throw new Error(`${logRes.status} ${logRes.statusText}`);
          }
        } else {
          throw new Error(`${addRes.status} ${addRes.statusText}`);
        }
      } else {
        throw new Error(`${res.status} ${res.statusText}`);
      }
    }
    "
  - text: 我还可以通过传递可选参数 from & to 或 limit 来检索任何用户的部分日志。(日期格式如: yyyy-mm-dd, limit = int)
    testString: "async getUserInput => {
      const url = getUserInput('url');
      const res = await fetch(url + '/api/exercise/new-user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: `username=fcc_test_${Date.now()}`.substr(0, 29)
      });

      if (res.ok) {
        const { _id, username } = await res.json();
        const expected = {
          username,
          description: 'test',
          duration: 60,
          _id,
          date: new Date().toDateString()
        };

        const addExerciseRes = await fetch(url + '/api/exercise/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `userId=${_id}&description=${expected.description}&duration=${expected.duration}&date=1990-01-01`
        });
        const addExerciseTwoRes = await fetch(url + '/api/exercise/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `userId=${_id}&description=${expected.description}&duration=${expected.duration}&date=1990-01-02`
        });
        if (addExerciseRes.ok && addExerciseTwoRes.ok) {
          const logRes = await fetch(
            url + `/api/exercise/log?userId=${_id}&from=1989-12-31&to=1990-01-03`
          );
          if (logRes.ok) {
            const { log } = await logRes.json();
            assert.isArray(log);
            assert.equal(2, log.length);
          } else {
            throw new Error(`${logRes.status} ${logRes.statusText}`);
          }

          const limitRes = await fetch(
            url + `/api/exercise/log?userId=${_id}&limit=1`
          );
          if (limitRes.ok) {
            const { log } = await limitRes.json();
            assert.isArray(log);
            assert.equal(1, log.length);
          } else {
            throw new Error(`${limitRes.status} ${limitRes.statusText}`);
          }
        } else {
          throw new Error(`${res.status} ${res.statusText}`);
        }
      } else {
        throw new Error(`${res.status} ${res.statusText}`);
      }
    }
    "

Challenge Seed

Solution

/**
  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.
*/