Oliver Eyton-Williams ee1e8abd87
feat(curriculum): restore seed + solution to Chinese (#40683)
* feat(tools): add seed/solution restore script

* chore(curriculum): remove empty sections' markers

* chore(curriculum): add seed + solution to Chinese

* chore: remove old formatter

* fix: update getChallenges

parse translated challenges separately, without reference to the source

* chore(curriculum): add dashedName to English

* chore(curriculum): add dashedName to Chinese

* refactor: remove unused challenge property 'name'

* fix: relax dashedName requirement

* fix: stray tag

Remove stray `pre` tag from challenge file.

Signed-off-by: nhcarrigan <nhcarrigan@gmail.com>

Co-authored-by: nhcarrigan <nhcarrigan@gmail.com>
2021-01-12 19:31:00 -07:00

6.9 KiB
Raw Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5a8b073d06fa14fcfde687aa 运动跟踪器 4 301505 exercise-tracker

--description--

构建一个功能类似于 https://fuschia-custard.glitch.me/ 的 JavaScript 全栈应用。

在开发这个项目时,我们推荐你在 Glitch 上编码。编码完成之后,你可以把应用主页的链接复制到屏幕的输入框中,测试你的代码是否能通过项目需求。当然你也可以基于其他的平台来完成自己的项目,只要提供一个公开的主页便于我们测试就行。

参考示例:你可以通过 这个链接 访问在 Glitch 上的项目,或者从 GitHub 上 clone 这个仓库的代码。如果你使用 Glitch请记住将项目链接保存到妥当的地方。

--hints--

提供独立的项目, 而不是例程 url.

(getUserInput) => {
  const url = getUserInput('url');
  assert(
    !new RegExp('.*/fuschia-custard.glitch.me.*').test(getUserInput('url'))
  );
};

通过指定 /api/exercise/new-user 的 username 参数来创建用户, 并且返回一个具有 username 和 _id 的对象。

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}`);
  }
};

通过指定 api/exercise/users 的参数为创建用户时相同的信息,来获取到一个用户的数组。

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}`);
  }
};

通过指定 /api/exercise/add 的 userId、description、duration 和 date可选参数, 去添加一条练习记录。 当没有传入 date 的时候,默认采用当前日期。 应用程序将返回添加了练习字段的用户对象。

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}`);
  }
};

通过指定 /api/exercise/log 的 userId 参数,可以获取任意用户的练习日志和总的练习次数。

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}`);
  }
};

我还可以通过传递可选参数 from & to 或 limit 来检索任何用户的部分日志。(日期格式如: yyyy-mm-dd, limit = int)

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}`);
  }
};

--solutions--

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