Compare commits
72 Commits
master
...
vehicle-pa
| Author | SHA1 | Date | |
|---|---|---|---|
| 5df1f1769e | |||
| add48e09a8 | |||
| 16a0dc47da | |||
| 3a8c052d86 | |||
| c3bb17f863 | |||
| cf9381309e | |||
| 21f3ed77a4 | |||
| 2e35d86e1a | |||
| 5bab5b2041 | |||
| 188625a413 | |||
| a9771243a1 | |||
| 540521f236 | |||
| 67680804e2 | |||
| fffbc87964 | |||
| d8cfe69fa0 | |||
| e7e6ed91f8 | |||
| 1801fd54ae | |||
| c416542449 | |||
| e1619de1cd | |||
| 18be371f39 | |||
| 734b924390 | |||
| 24d3a962bd | |||
| 432ff2ac14 | |||
| 1cf3dba078 | |||
| cf59911c4c | |||
| 3782c90647 | |||
| f2ba114d26 | |||
| 0ea1c855d2 | |||
| 5787c9d8db | |||
| 8a5958dde0 | |||
| 0408b8bf63 | |||
| f937bfcf4c | |||
| ab465bbe16 | |||
| 214921a6e8 | |||
| 10808b66b2 | |||
| baed9969b2 | |||
| a413b6f637 | |||
| a7a30c37df | |||
| 111558309e | |||
| 9394950263 | |||
| 23595f0e58 | |||
| 6941293c14 | |||
| f95a384409 | |||
| f2de531fd9 | |||
| b3afb2b66f | |||
| 4ae4b4ecd9 | |||
| 1b36ad6a81 | |||
| c77fe19ed1 | |||
| 0b7b64231d | |||
| 5de7b3d676 | |||
| cde972e20e | |||
| e1827b3b7d | |||
| 444d3f8326 | |||
| c08b0575dc | |||
| 62862e6c14 | |||
| bca6a2ed11 | |||
| e2051c8d74 | |||
| 407ef3dcd1 | |||
| 467eb68e25 | |||
| 7935ae750f | |||
| eac90cffd6 | |||
| e8cc9c89ba | |||
| 7b52deccd8 | |||
| 1a86713c00 | |||
| 7d60872823 | |||
| ea89471cc0 | |||
| 050942c679 | |||
| c329368906 | |||
| 2b2528054a | |||
| 1278e23aec | |||
| 80b7c19e27 | |||
| 5328f5eb51 |
16
.babelrc
Normal file
16
.babelrc
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"test": {
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"node": "current"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
44
.github/workflows/ci.yml
vendored
Normal file
44
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
node: [14]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout 🛎
|
||||||
|
uses: actions/checkout@master
|
||||||
|
|
||||||
|
- name: Setup node env 🏗
|
||||||
|
uses: actions/setup-node@v2.1.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
|
||||||
|
- name: Cache node_modules 📦
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
|
||||||
|
- name: Install dependencies 👨🏻💻
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
|
||||||
|
- name: Run tests 🧪
|
||||||
|
run: npm run test
|
||||||
90
.gitignore
vendored
Normal file
90
.gitignore
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Node template
|
||||||
|
# Logs
|
||||||
|
/logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# Nuxt generate
|
||||||
|
dist
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless
|
||||||
|
|
||||||
|
# IDE / Editor
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Service worker
|
||||||
|
sw.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Vim swap files
|
||||||
|
*.swp
|
||||||
19
README.md
19
README.md
@@ -1,5 +1,24 @@
|
|||||||
# Ghibli API
|
# Ghibli API
|
||||||
|
|
||||||
|
## Build Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# install dependencies
|
||||||
|
$ npm install
|
||||||
|
|
||||||
|
# serve with hot reload at localhost:3000
|
||||||
|
$ npm run dev
|
||||||
|
|
||||||
|
# build for production and launch server
|
||||||
|
$ npm run build
|
||||||
|
$ npm run start
|
||||||
|
|
||||||
|
# generate static project
|
||||||
|
$ npm run generate
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Using [the Ghibli API](https://ghibliapi.herokuapp.com), you will build an app with the following features:
|
Using [the Ghibli API](https://ghibliapi.herokuapp.com), you will build an app with the following features:
|
||||||
|
|||||||
7
assets/README.md
Normal file
7
assets/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# ASSETS
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
|
||||||
3
assets/css/tailwind.css
Normal file
3
assets/css/tailwind.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
BIN
assets/images/logo.png
Normal file
BIN
assets/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
56
assets/svg/rotten-tomatoes.svg
Normal file
56
assets/svg/rotten-tomatoes.svg
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<svg
|
||||||
|
width="80px"
|
||||||
|
height="80px"
|
||||||
|
viewBox="0 0 80 80"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
>
|
||||||
|
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||||
|
<title>Icons/Tomatometer & AS/fresh</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs>
|
||||||
|
<polygon
|
||||||
|
id="path-1"
|
||||||
|
points="0.000109100102 0.246970954 77.0827837 0.246970954 77.0827837 63.7145228 0.000109100102 63.7145228"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="Icons/Tomatometer-&-AS/fresh"
|
||||||
|
stroke="none"
|
||||||
|
stroke-width="1"
|
||||||
|
fill="none"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
>
|
||||||
|
<g id="Group">
|
||||||
|
<rect
|
||||||
|
id="Rectangle-Copy-2"
|
||||||
|
fill="#000000"
|
||||||
|
opacity="0"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="80"
|
||||||
|
height="80"
|
||||||
|
/>
|
||||||
|
<g id="RT_Fresh_Tomato_RGB-(1)" transform="translate(1.327801, 0.000000)">
|
||||||
|
<g id="Group-3" transform="translate(0.000000, 16.265560)">
|
||||||
|
<mask id="mask-2" fill="white">
|
||||||
|
<use xlink:href="#path-1" />
|
||||||
|
</mask>
|
||||||
|
<g id="Clip-2" />
|
||||||
|
<path
|
||||||
|
d="M77.0137759,27.0426556 C76.2423237,14.6741909 69.9521992,5.42041494 60.4876349,0.246970954 C60.5414108,0.548381743 60.273195,0.925145228 59.9678008,0.791701245 C53.7772614,-1.91634855 43.2753527,6.84780083 35.9365975,2.25825726 C35.9917012,3.90539419 35.6700415,11.940249 24.3515353,12.4063071 C24.0843154,12.4172614 23.9372614,12.1443983 24.1062241,11.9512033 C25.619917,10.2247303 27.1482158,5.85360996 24.9507054,3.5233195 C20.2446473,7.74041494 17.5117012,9.32746888 8.48829876,7.23319502 C2.71103734,13.2740249 -0.562655602,21.5419087 0.08,31.8413278 C1.39120332,52.86639 21.0848133,64.8846473 40.9165145,63.6471369 C60.746888,62.4106224 78.3253112,48.0677178 77.0137759,27.0426556"
|
||||||
|
id="Fill-1"
|
||||||
|
fill="#FA320A"
|
||||||
|
mask="url(#mask-2)"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d="M40.8717012,11.4648963 C44.946722,10.49361 56.6678838,11.3702905 60.4232365,16.3518672 C60.6486307,16.6506224 60.3312863,17.2159336 59.9678008,17.0572614 C53.7772614,14.3492116 43.2753527,23.113361 35.9365975,18.5238174 C35.9917012,20.1709544 35.6700415,28.2058091 24.3515353,28.6718672 C24.0843154,28.6828216 23.9372614,28.4099585 24.1062241,28.2167635 C25.619917,26.4902905 27.1478838,22.1191701 24.9507054,19.7888797 C19.8243983,24.3827386 17.0453112,25.8589212 5.91900415,22.8514523 C5.55485477,22.753195 5.67900415,22.1679668 6.06639004,22.020249 C8.16929461,21.2165975 12.933444,17.6965975 17.4406639,16.1450622 C18.2987552,15.8499585 19.1541909,15.6209129 19.9890456,15.4878008 C15.02639,15.0443154 12.7893776,14.3541909 9.63286307,14.8302075 C9.28697095,14.8823237 9.05195021,14.479668 9.26639004,14.2034855 C13.5193361,8.7253112 21.3540249,7.07087137 26.1878838,9.98107884 C23.2082988,6.28912863 20.8743568,3.34473029 20.8743568,3.34473029 L26.4046473,0.203485477 C26.4046473,0.203485477 28.6894606,5.30821577 30.3518672,9.02340249 C34.4657261,2.94506224 42.119834,2.38406639 45.3536929,6.69676349 C45.5455602,6.95302905 45.3450622,7.31751037 45.0247303,7.30987552 C42.3926971,7.24580913 40.9434025,9.63983402 40.833527,11.4605809 L40.8717012,11.4648963"
|
||||||
|
id="Fill-4"
|
||||||
|
fill="#00912D"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
30
components/Film/Film.spec.js
Normal file
30
components/Film/Film.spec.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { mount, RouterLinkStub } from "@vue/test-utils";
|
||||||
|
import Film from "./";
|
||||||
|
import mockFilms from "@/test/fake-films.json";
|
||||||
|
|
||||||
|
describe("Film", () => {
|
||||||
|
it("tests props", () => {
|
||||||
|
expect(Film.props).toMatchObject({
|
||||||
|
film: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders proper link to details", () => {
|
||||||
|
const wrapper = mount(Film, {
|
||||||
|
propsData: {
|
||||||
|
film: mockFilms[0]
|
||||||
|
},
|
||||||
|
stubs: {
|
||||||
|
RouterLink: RouterLinkStub
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe(
|
||||||
|
`/films/${mockFilms[0].id}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
108
components/Film/index.vue
Normal file
108
components/Film/index.vue
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<article
|
||||||
|
class="film flex flex-col justify-between bg-gray-100 prose prose-sm rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl mb-4 sm:m-4"
|
||||||
|
>
|
||||||
|
<header class="p-4 rounded-t-md">
|
||||||
|
<h1>
|
||||||
|
{{ film.title + " (" + film.release_date + ")" }}
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-gray-700 mt-0">{{ "by " + film.director }}</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="inline-block px-4">
|
||||||
|
<h3>Summary</h3>
|
||||||
|
<p>{{ excerptOfDescription }}</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="px-4 flex items-center justify-between">
|
||||||
|
<p
|
||||||
|
class="film-score font-bold text-lg"
|
||||||
|
:class="{
|
||||||
|
'text-green-600': film.rt_score >= 75,
|
||||||
|
'text-orange-600': film.rt_score >= 50 && film.rt_score < 75,
|
||||||
|
'text-yellow-600': film.rt_score >= 25 && film.rt_score < 50,
|
||||||
|
'text-red-600': film.rt_score >= 0 && film.rt_score < 25
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ film.rt_score + "%" }}
|
||||||
|
</p>
|
||||||
|
<router-link
|
||||||
|
class="rounded font-semibold bg-gray-400 py-2 px-4 border-b-4 border-gray-500"
|
||||||
|
:to="`/films/${film.id}`"
|
||||||
|
tag="button"
|
||||||
|
>
|
||||||
|
Read more
|
||||||
|
</router-link>
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Film",
|
||||||
|
props: {
|
||||||
|
film: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
excerptOfDescription: function() {
|
||||||
|
return this.film.description.substring(0, 300) + "...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
@media screen and (min-width: 640px) {
|
||||||
|
.film {
|
||||||
|
margin: 1rem;
|
||||||
|
flex: 1 1 calc(50% - 2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1024px) {
|
||||||
|
.film {
|
||||||
|
flex: 1 1 calc(33% - 2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background-color: #85ffbd;
|
||||||
|
background-image: linear-gradient(45deg, #85ffbd 0%, #fffb7d 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.film:nth-child(2n) header {
|
||||||
|
background-color: #ff9a8b;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
#ff9a8b 0%,
|
||||||
|
#ff6a88 55%,
|
||||||
|
#ff99ac 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.film:nth-child(4n) header {
|
||||||
|
background-color: #fee140;
|
||||||
|
background-image: linear-gradient(90deg, #fee140 0%, #fa709a 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.film:nth-child(5n) header {
|
||||||
|
background-color: #a9c9ff;
|
||||||
|
background-image: linear-gradient(180deg, #a9c9ff 0%, #ffbbec 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.film-score::before {
|
||||||
|
content: "";
|
||||||
|
background: url(~assets/svg/rotten-tomatoes.svg);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100%;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: sub;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
components/Footer/Footer.spec.js
Normal file
9
components/Footer/Footer.spec.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
import Footer from "./";
|
||||||
|
|
||||||
|
describe("Footer", () => {
|
||||||
|
it("should render Footer instance", () => {
|
||||||
|
const wrapper = mount(Footer);
|
||||||
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
18
components/Footer/index.vue
Normal file
18
components/Footer/index.vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<footer
|
||||||
|
class="bg-gray-900 text-gray-300 flex items-center justify-center h-16"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
©2020 Made with <span style="color: red;">♥</span> by
|
||||||
|
<a href="https://wazo-lab.io" target="_blank">Wazo Lab</a>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Footer"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
26
components/Grid/Grid.spec.js
Normal file
26
components/Grid/Grid.spec.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import Grid from "./";
|
||||||
|
import mockFilms from "@/test/fake-films.json";
|
||||||
|
|
||||||
|
describe("Grid", () => {
|
||||||
|
it("tests props", () => {
|
||||||
|
expect(Grid.props).toMatchObject({
|
||||||
|
dataSource: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render Grid instance with expected Film components", () => {
|
||||||
|
const wrapper = shallowMount(Grid, {
|
||||||
|
propsData: {
|
||||||
|
dataSource: mockFilms
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.findAllComponents({ name: "Film" }).length).toBe(
|
||||||
|
mockFilms.length
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
22
components/Grid/index.vue
Normal file
22
components/Grid/index.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex flex-wrap justify-center">
|
||||||
|
<Film :key="film.id" v-for="film in dataSource" :film="film" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Film from "../Film";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Film },
|
||||||
|
name: "Grid",
|
||||||
|
props: {
|
||||||
|
dataSource: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
18
components/Header/Header.spec.js
Normal file
18
components/Header/Header.spec.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { mount, RouterLinkStub } from "@vue/test-utils";
|
||||||
|
import Header from "./";
|
||||||
|
|
||||||
|
describe("Header", () => {
|
||||||
|
it("should render Header instance", () => {
|
||||||
|
const wrapper = mount(Header, { stubs: ["router-link"] });
|
||||||
|
expect(wrapper.find("h1").text()).toBe("PeopleDoc");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should redirect to Home page when clicking on brand logo", () => {
|
||||||
|
const wrapper = mount(Header, {
|
||||||
|
stubs: {
|
||||||
|
RouterLink: RouterLinkStub
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe("/");
|
||||||
|
});
|
||||||
|
});
|
||||||
31
components/Header/index.vue
Normal file
31
components/Header/index.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<header
|
||||||
|
id="header"
|
||||||
|
class="fixed top-0 left-0 w-screen bg-white h-16 px-4 md:px-8 py-3 shadow-md flex items-center justify-between"
|
||||||
|
>
|
||||||
|
<router-link to="/" class="flex w-auto h-full items-center">
|
||||||
|
<img
|
||||||
|
class="h-full mr-4"
|
||||||
|
src="https://avatars2.githubusercontent.com/u/1080062?s=200&v=4"
|
||||||
|
alt="PeopleDoc - Icon"
|
||||||
|
/>
|
||||||
|
<h1 class="text-2xl font-light tracking-wide">PeopleDoc</h1>
|
||||||
|
</router-link>
|
||||||
|
<h2 class="font-medium hidden sm:block">{{ description }}</h2>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import pkg from "@/package.json";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Header",
|
||||||
|
computed: {
|
||||||
|
description: function() {
|
||||||
|
return pkg.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
30
components/Location/Location.spec.js
Normal file
30
components/Location/Location.spec.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { mount, RouterLinkStub } from "@vue/test-utils";
|
||||||
|
import Location from "./";
|
||||||
|
import mockLocation from "@/test/fake-locations.json";
|
||||||
|
|
||||||
|
describe("Location", () => {
|
||||||
|
it("tests props", () => {
|
||||||
|
expect(Location.props).toMatchObject({
|
||||||
|
location: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders proper link to details", () => {
|
||||||
|
const wrapper = mount(Location, {
|
||||||
|
propsData: {
|
||||||
|
location: mockLocation[0]
|
||||||
|
},
|
||||||
|
stubs: {
|
||||||
|
RouterLink: RouterLinkStub
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe(
|
||||||
|
`/locations/${mockLocation[0].id}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
27
components/Location/index.vue
Normal file
27
components/Location/index.vue
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<router-link
|
||||||
|
class="location flex items-center cursor-pointer p-3 mb-2 rounded bg-gray-300 hover:bg-gray-400"
|
||||||
|
:to="`/locations/${location.id}`"
|
||||||
|
tag="article"
|
||||||
|
>
|
||||||
|
<span class="mr-2 text-sm rounded-xl px-2 py-1">{{
|
||||||
|
location.terrain
|
||||||
|
}}</span>
|
||||||
|
<h4>{{ location.name }}</h4>
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Location",
|
||||||
|
props: {
|
||||||
|
location: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
30
components/Person/Person.spec.js
Normal file
30
components/Person/Person.spec.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { mount, RouterLinkStub } from "@vue/test-utils";
|
||||||
|
import Person from "./";
|
||||||
|
import mockPeople from "@/test/fake-people.json";
|
||||||
|
|
||||||
|
describe("Person", () => {
|
||||||
|
it("tests props", () => {
|
||||||
|
expect(Person.props).toMatchObject({
|
||||||
|
person: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders proper link to details", () => {
|
||||||
|
const wrapper = mount(Person, {
|
||||||
|
propsData: {
|
||||||
|
person: mockPeople[0]
|
||||||
|
},
|
||||||
|
stubs: {
|
||||||
|
RouterLink: RouterLinkStub
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe(
|
||||||
|
`/people/${mockPeople[0].id}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
27
components/Person/index.vue
Normal file
27
components/Person/index.vue
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<router-link
|
||||||
|
class="person flex items-center cursor-pointer p-3 mb-2 rounded bg-gray-300 hover:bg-gray-400"
|
||||||
|
:to="`/people/${person.id}`"
|
||||||
|
tag="article"
|
||||||
|
>
|
||||||
|
<span class="mr-2 text-xl font-bold">{{
|
||||||
|
person.gender === "Female" ? "♀" : "♂"
|
||||||
|
}}</span>
|
||||||
|
<h4>{{ person.name }}</h4>
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Person",
|
||||||
|
props: {
|
||||||
|
person: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
7
components/README.md
Normal file
7
components/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# COMPONENTS
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
The components directory contains your Vue.js Components.
|
||||||
|
|
||||||
|
_Nuxt.js doesn't supercharge these components._
|
||||||
30
components/Vehicle/Vehicle.spec.js
Normal file
30
components/Vehicle/Vehicle.spec.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { mount, RouterLinkStub } from "@vue/test-utils";
|
||||||
|
import Vehicle from "./";
|
||||||
|
import mockVehicles from "@/test/fake-vehicles.json";
|
||||||
|
|
||||||
|
describe("Vehicle", () => {
|
||||||
|
it("tests props", () => {
|
||||||
|
expect(Vehicle.props).toMatchObject({
|
||||||
|
vehicle: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders proper link to details", () => {
|
||||||
|
const wrapper = mount(Vehicle, {
|
||||||
|
propsData: {
|
||||||
|
vehicle: mockVehicles[0]
|
||||||
|
},
|
||||||
|
stubs: {
|
||||||
|
RouterLink: RouterLinkStub
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe(
|
||||||
|
`/vehicles/${mockVehicles[0].id}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
33
components/Vehicle/index.vue
Normal file
33
components/Vehicle/index.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<router-link
|
||||||
|
class="vehicle flex items-center cursor-pointer p-3 mb-2 rounded bg-gray-300 hover:bg-gray-400"
|
||||||
|
:to="`/vehicles/${vehicle.id}`"
|
||||||
|
tag="article"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="mr-2 text-sm rounded-xl px-2 py-1"
|
||||||
|
:class="{
|
||||||
|
'bg-teal-400': vehicle.vehicle_class === 'Airship',
|
||||||
|
'bg-red-400': vehicle.vehicle_class === 'Airplane',
|
||||||
|
'bg-orange-400': vehicle.vehicle_class === 'Boat'
|
||||||
|
}"
|
||||||
|
>{{ vehicle.vehicle_class }}</span
|
||||||
|
>
|
||||||
|
<h4>{{ vehicle.name }}</h4>
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Vehicle",
|
||||||
|
props: {
|
||||||
|
vehicle: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
18
jest.config.js
Normal file
18
jest.config.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
module.exports = {
|
||||||
|
moduleNameMapper: {
|
||||||
|
"^@/(.*)$": "<rootDir>/$1",
|
||||||
|
"^~/(.*)$": "<rootDir>/$1",
|
||||||
|
"^vue$": "vue/dist/vue.common.js"
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ["js", "vue", "json"],
|
||||||
|
transform: {
|
||||||
|
"^.+\\.js$": "babel-jest",
|
||||||
|
".*\\.(vue)$": "vue-jest"
|
||||||
|
},
|
||||||
|
coverageDirectory: "<rootDir>/coverage",
|
||||||
|
collectCoverage: true,
|
||||||
|
collectCoverageFrom: [
|
||||||
|
"<rootDir>/components/**/*.vue",
|
||||||
|
"<rootDir>/pages/**/*.vue"
|
||||||
|
]
|
||||||
|
};
|
||||||
11
jsconfig.json
Normal file
11
jsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2015",
|
||||||
|
"module": "esnext",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["components/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["./**/*.vue", "./**/*.js"]
|
||||||
|
}
|
||||||
7
layouts/README.md
Normal file
7
layouts/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# LAYOUTS
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains your Application Layouts.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
|
||||||
50
layouts/default.vue
Normal file
50
layouts/default.vue
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Header />
|
||||||
|
<main class="mt-16 px-4">
|
||||||
|
<Nuxt />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
middleware: ["redirect"],
|
||||||
|
fetchOnServer: false,
|
||||||
|
async fetch() {
|
||||||
|
const { store } = this.$nuxt.context;
|
||||||
|
if (!store.state.films.list.length) await store.dispatch("films/getList");
|
||||||
|
if (!store.state.people.list.length) await store.dispatch("people/getList");
|
||||||
|
if (!store.state.vehicles.list.length)
|
||||||
|
await store.dispatch("vehicles/getList");
|
||||||
|
if (!store.state.locations.list.length)
|
||||||
|
await store.dispatch("locations/getList");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI",
|
||||||
|
Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
word-spacing: 1px;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
min-height: calc(100vh - 64px * 2);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
8
middleware/README.md
Normal file
8
middleware/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# MIDDLEWARE
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains your application middleware.
|
||||||
|
Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
|
||||||
3
middleware/redirect.js
Normal file
3
middleware/redirect.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default function({ redirect, route }) {
|
||||||
|
if (route.path === "/") redirect("/films");
|
||||||
|
}
|
||||||
54
nuxt.config.js
Normal file
54
nuxt.config.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
export default {
|
||||||
|
// Disable server-side rendering (https://go.nuxtjs.dev/ssr-mode)
|
||||||
|
ssr: false,
|
||||||
|
|
||||||
|
// Target (https://go.nuxtjs.dev/config-target)
|
||||||
|
target: "static",
|
||||||
|
|
||||||
|
// Global page headers (https://go.nuxtjs.dev/config-head)
|
||||||
|
head: {
|
||||||
|
title: "Ghibli",
|
||||||
|
meta: [
|
||||||
|
{ charset: "utf-8" },
|
||||||
|
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||||
|
{
|
||||||
|
hid: "description",
|
||||||
|
name: "description",
|
||||||
|
content: "A test project for PeopleDoc."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }]
|
||||||
|
},
|
||||||
|
|
||||||
|
// Global CSS (https://go.nuxtjs.dev/config-css)
|
||||||
|
css: [],
|
||||||
|
|
||||||
|
// Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
|
||||||
|
plugins: [],
|
||||||
|
|
||||||
|
// Auto import components (https://go.nuxtjs.dev/config-components)
|
||||||
|
components: true,
|
||||||
|
|
||||||
|
// Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
|
||||||
|
buildModules: [
|
||||||
|
// https://go.nuxtjs.dev/tailwindcss
|
||||||
|
"@nuxtjs/tailwindcss"
|
||||||
|
],
|
||||||
|
|
||||||
|
// Modules (https://go.nuxtjs.dev/config-modules)
|
||||||
|
modules: ["@nuxtjs/axios"],
|
||||||
|
|
||||||
|
axios: {
|
||||||
|
proxy: true
|
||||||
|
},
|
||||||
|
|
||||||
|
proxy: {
|
||||||
|
"/api/": {
|
||||||
|
target: "https://ghibliapi.herokuapp.com",
|
||||||
|
pathRewrite: { "^/api/": "" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Build Configuration (https://go.nuxtjs.dev/config-build)
|
||||||
|
build: {}
|
||||||
|
};
|
||||||
15175
package-lock.json
generated
Normal file
15175
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "ghibli-api",
|
||||||
|
"description": "A test project for PeopleDoc.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nuxt",
|
||||||
|
"build": "nuxt build",
|
||||||
|
"start": "nuxt start",
|
||||||
|
"generate": "nuxt generate",
|
||||||
|
"test": "jest"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxtjs/axios": "^5.12.4",
|
||||||
|
"@tailwindcss/typography": "^0.3.1",
|
||||||
|
"core-js": "^3.6.5",
|
||||||
|
"nuxt": "^2.14.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@nuxtjs/tailwindcss": "^3.1.0",
|
||||||
|
"@vue/test-utils": "^1.1.0",
|
||||||
|
"babel-core": "7.0.0-bridge.0",
|
||||||
|
"babel-jest": "^26.5.0",
|
||||||
|
"jest": "^26.5.0",
|
||||||
|
"vue-jest": "^3.0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
pages/README.md
Normal file
6
pages/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# PAGES
|
||||||
|
|
||||||
|
This directory contains your Application Views and Routes.
|
||||||
|
The framework reads all the `*.vue` files inside this directory and creates the router of your application.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
|
||||||
81
pages/films/_id.spec.js
Normal file
81
pages/films/_id.spec.js
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { mount, createLocalVue } from "@vue/test-utils";
|
||||||
|
import Vuex from "vuex";
|
||||||
|
import Film from "./_id";
|
||||||
|
import mockFilms from "@/test/fake-films.json";
|
||||||
|
|
||||||
|
let $route = {
|
||||||
|
path: "/films",
|
||||||
|
params: {
|
||||||
|
id: "2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const localVue = createLocalVue();
|
||||||
|
localVue.use(Vuex);
|
||||||
|
|
||||||
|
describe("Film page", () => {
|
||||||
|
let state, actions, store;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
state = {
|
||||||
|
film: {}
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
getFilm: jest.fn()
|
||||||
|
};
|
||||||
|
|
||||||
|
store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
films: {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render Film page instance", () => {
|
||||||
|
const wrapper = mount(Film, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
film: () => mockFilms[0],
|
||||||
|
people: () => jest.fn(),
|
||||||
|
vehicles: () => jest.fn(),
|
||||||
|
locations: () => jest.fn()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("tests params validation", () => {
|
||||||
|
expect(Film.validate({ params: $route.params })).toBe(true);
|
||||||
|
expect(
|
||||||
|
Film.validate({
|
||||||
|
params: { id: "2baf70d1-42bb-4437-b551-e5fed5a87abe-1234" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
Film.validate({
|
||||||
|
params: { id: "2baf7e0d1-42bb-4437-b551-e5fed5a87abe" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch getFilm action", async () => {
|
||||||
|
let wrapper = mount(Film, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
film: () => mockFilms[0],
|
||||||
|
people: () => jest.fn(),
|
||||||
|
vehicles: () => jest.fn(),
|
||||||
|
locations: () => jest.fn()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await wrapper.vm.$options.asyncData({ store, params: $route.params });
|
||||||
|
expect(actions.getFilm).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
129
pages/films/_id.vue
Normal file
129
pages/films/_id.vue
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="py-4 flex flex-col lg:flex-row items-center lg:items-start justify-center"
|
||||||
|
>
|
||||||
|
<article
|
||||||
|
class="mb-4 inline-flex flex-col justify-between bg-gray-100 prose prose-sm rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
|
||||||
|
>
|
||||||
|
<header class="p-4 rounded-t-md">
|
||||||
|
<h1>
|
||||||
|
{{ film.title + " (" + film.release_date + ")" }}
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-gray-700 mt-0">{{ "by " + film.director }}</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="px-4 infos">
|
||||||
|
<p>{{ film.description }}</p>
|
||||||
|
<p
|
||||||
|
class="film-score font-bold text-lg"
|
||||||
|
:class="{
|
||||||
|
'text-green-600': film.rt_score >= 75,
|
||||||
|
'text-orange-600': film.rt_score >= 50 && film.rt_score < 75,
|
||||||
|
'text-yellow-600': film.rt_score >= 25 && film.rt_score < 50,
|
||||||
|
'text-red-600': film.rt_score >= 0 && film.rt_score < 25
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ film.rt_score + "%" }}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<aside class="lg:inline-flex lg:ml-4">
|
||||||
|
<section
|
||||||
|
class="p-4 lg:mr-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
|
||||||
|
>
|
||||||
|
<h3 class="font-medium text-lg mb-4">People</h3>
|
||||||
|
<ul v-if="people.length">
|
||||||
|
<li :key="person.id" v-for="person in people">
|
||||||
|
<Person :person="person" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="p-4 lg:mr-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
|
||||||
|
>
|
||||||
|
<h3 class="font-medium text-lg mb-4">Vehicles</h3>
|
||||||
|
<ul v-if="vehicles.length">
|
||||||
|
<li :key="vehicle.id" v-for="vehicle in vehicles">
|
||||||
|
<Vehicle :vehicle="vehicle" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="p-4 lg:mr-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
|
||||||
|
>
|
||||||
|
<h3 class="font-medium text-lg">Locations</h3>
|
||||||
|
<ul v-if="locations.length">
|
||||||
|
<li :key="location.id" v-for="location in locations">
|
||||||
|
<Location :location="location" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Film",
|
||||||
|
components: {
|
||||||
|
Person: () => import("@/components/Person"),
|
||||||
|
Vehicle: () => import("@/components/Vehicle"),
|
||||||
|
Location: () => import("@/components/Location")
|
||||||
|
},
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
titleTemplate: `%s - ${this.film.title}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
validate({ params }) {
|
||||||
|
const uuid = new RegExp(
|
||||||
|
/^[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-4[0-9A-Za-z]{3}-[89ABab][0-9A-Za-z]{3}-[0-9A-Za-z]{12}$/
|
||||||
|
);
|
||||||
|
return uuid.test(params.id);
|
||||||
|
},
|
||||||
|
async asyncData({ params, store }) {
|
||||||
|
if (!store.state.films.film.id !== params.id)
|
||||||
|
await store.dispatch("films/getFilm", params.id);
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
people() {
|
||||||
|
return this.$store.getters["people/getPeopleByFilmId"](this.film.id);
|
||||||
|
},
|
||||||
|
vehicles() {
|
||||||
|
return this.$store.getters["vehicles/getVehiclesByFilmId"](this.film.id);
|
||||||
|
},
|
||||||
|
locations() {
|
||||||
|
return this.$store.getters["locations/getLocationsByFilmId"](
|
||||||
|
this.film.id
|
||||||
|
);
|
||||||
|
},
|
||||||
|
...mapGetters({
|
||||||
|
film: "films/film"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css">
|
||||||
|
article header {
|
||||||
|
background-color: #85ffbd;
|
||||||
|
background-image: linear-gradient(45deg, #85ffbd 0%, #fffb7d 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.film-score::before {
|
||||||
|
content: "";
|
||||||
|
background: url(~assets/svg/rotten-tomatoes.svg);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100%;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: sub;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
48
pages/films/index.spec.js
Normal file
48
pages/films/index.spec.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { shallowMount, createLocalVue } from "@vue/test-utils";
|
||||||
|
import Vuex from "vuex";
|
||||||
|
import Films from "./";
|
||||||
|
|
||||||
|
const localVue = createLocalVue();
|
||||||
|
localVue.use(Vuex);
|
||||||
|
|
||||||
|
describe("Films page", () => {
|
||||||
|
let state, actions, getters, store;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
state = {
|
||||||
|
list: []
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
getList: jest.fn()
|
||||||
|
};
|
||||||
|
getters = {
|
||||||
|
list: jest.fn()
|
||||||
|
};
|
||||||
|
store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
films: {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
actions,
|
||||||
|
getters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render Films page instance", () => {
|
||||||
|
const wrapper = shallowMount(Films, { store, localVue });
|
||||||
|
expect(wrapper.find("img").exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch films/getList action", async () => {
|
||||||
|
let wrapper = shallowMount(Films, {
|
||||||
|
store,
|
||||||
|
localVue
|
||||||
|
});
|
||||||
|
|
||||||
|
await wrapper.vm.$options.asyncData({ store });
|
||||||
|
expect(actions.getList).toHaveBeenCalled();
|
||||||
|
expect(wrapper.findComponent({ name: "Grid" }).exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
33
pages/films/index.vue
Normal file
33
pages/films/index.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<section class="py-4">
|
||||||
|
<img
|
||||||
|
class="w-full max-w-md mx-auto mb-8"
|
||||||
|
src="~/assets/images/logo.png"
|
||||||
|
alt="Studio Ghibli"
|
||||||
|
/>
|
||||||
|
<Grid :dataSource="films" />
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Grid from "@/components/Grid";
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Films",
|
||||||
|
components: { Grid },
|
||||||
|
head: {
|
||||||
|
titleTemplate: "%s - Films"
|
||||||
|
},
|
||||||
|
async asyncData({ store }) {
|
||||||
|
if (!store.state.films.list.length) await store.dispatch("films/getList");
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
films: "films/list"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
74
pages/locations/_id.spec.js
Normal file
74
pages/locations/_id.spec.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { mount, createLocalVue } from "@vue/test-utils";
|
||||||
|
import Vuex from "vuex";
|
||||||
|
import Location from "./_id";
|
||||||
|
import mockLocations from "@/test/fake-locations.json";
|
||||||
|
|
||||||
|
let $route = {
|
||||||
|
path: "/locations",
|
||||||
|
params: {
|
||||||
|
id: "2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const localVue = createLocalVue();
|
||||||
|
localVue.use(Vuex);
|
||||||
|
|
||||||
|
describe("Location page", () => {
|
||||||
|
let state, actions, store;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
state = {
|
||||||
|
location: {}
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
getLocation: jest.fn()
|
||||||
|
};
|
||||||
|
store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
locations: {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render Location page instance", () => {
|
||||||
|
const wrapper = mount(Location, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
location: () => mockLocations[0]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("tests params validation", () => {
|
||||||
|
expect(Location.validate({ params: $route.params })).toBe(true);
|
||||||
|
expect(
|
||||||
|
Location.validate({
|
||||||
|
params: { id: "2baf70d1-42bb-4437-b551-e5fed5a87abe-1234" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
Location.validate({
|
||||||
|
params: { id: "2baf7e0d1-42bb-4437-b551-e5fed5a87abe" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch getLocation action", async () => {
|
||||||
|
let wrapper = mount(Location, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
location: () => mockLocations[0]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await wrapper.vm.$options.asyncData({ store, params: $route.params });
|
||||||
|
expect(actions.getLocation).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
35
pages/locations/_id.vue
Normal file
35
pages/locations/_id.vue
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
{{ location }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Location",
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
titleTemplate: `%s - ${this.location.name}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
validate({ params }) {
|
||||||
|
const uuid = new RegExp(
|
||||||
|
/^[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-4[0-9A-Za-z]{3}-[89ABab][0-9A-Za-z]{3}-[0-9A-Za-z]{12}$/
|
||||||
|
);
|
||||||
|
return uuid.test(params.id);
|
||||||
|
},
|
||||||
|
async asyncData({ params, store }) {
|
||||||
|
if (!store.state.locations.location.id !== params.id)
|
||||||
|
await store.dispatch("locations/getLocation", params.id);
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
location: "locations/location"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
74
pages/people/_id.spec.js
Normal file
74
pages/people/_id.spec.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { mount, createLocalVue } from "@vue/test-utils";
|
||||||
|
import Vuex from "vuex";
|
||||||
|
import Person from "./_id";
|
||||||
|
import mockPeople from "@/test/fake-people.json";
|
||||||
|
|
||||||
|
let $route = {
|
||||||
|
path: "/people",
|
||||||
|
params: {
|
||||||
|
id: "2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const localVue = createLocalVue();
|
||||||
|
localVue.use(Vuex);
|
||||||
|
|
||||||
|
describe("Person page", () => {
|
||||||
|
let state, actions, store;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
state = {
|
||||||
|
person: {}
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
getPerson: jest.fn()
|
||||||
|
};
|
||||||
|
store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
people: {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render Person page instance", () => {
|
||||||
|
const wrapper = mount(Person, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
person: () => mockPeople[0]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("tests params validation", () => {
|
||||||
|
expect(Person.validate({ params: $route.params })).toBe(true);
|
||||||
|
expect(
|
||||||
|
Person.validate({
|
||||||
|
params: { id: "2baf70d1-42bb-4437-b551-e5fed5a87abe-1234" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
Person.validate({
|
||||||
|
params: { id: "2baf7e0d1-42bb-4437-b551-e5fed5a87abe" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch getPerson action", async () => {
|
||||||
|
let wrapper = mount(Person, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
person: () => mockPeople[0]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await wrapper.vm.$options.asyncData({ store, params: $route.params });
|
||||||
|
expect(actions.getPerson).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
35
pages/people/_id.vue
Normal file
35
pages/people/_id.vue
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
{{ person }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Person",
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
titleTemplate: `%s - ${this.person.name}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
validate({ params }) {
|
||||||
|
const uuid = new RegExp(
|
||||||
|
/^[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-4[0-9A-Za-z]{3}-[89ABab][0-9A-Za-z]{3}-[0-9A-Za-z]{12}$/
|
||||||
|
);
|
||||||
|
return uuid.test(params.id);
|
||||||
|
},
|
||||||
|
async asyncData({ params, store }) {
|
||||||
|
if (!store.state.people.person.id !== params.id)
|
||||||
|
await store.dispatch("people/getPerson", params.id);
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
person: "people/person"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
82
pages/vehicles/_id.spec.js
Normal file
82
pages/vehicles/_id.spec.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { mount, createLocalVue } from "@vue/test-utils";
|
||||||
|
import Vuex from "vuex";
|
||||||
|
import Vehicle from "./_id";
|
||||||
|
import mockVehicles from "@/test/fake-vehicles.json";
|
||||||
|
import mockPeople from "@/test/fake-people.json";
|
||||||
|
import mockFilms from "@/test/fake-films.json";
|
||||||
|
|
||||||
|
let $route = {
|
||||||
|
path: "/vehicles",
|
||||||
|
params: {
|
||||||
|
id: "2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const localVue = createLocalVue();
|
||||||
|
localVue.use(Vuex);
|
||||||
|
|
||||||
|
describe("Vehicle page", () => {
|
||||||
|
let state, actions, store;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
state = {
|
||||||
|
vehicle: {}
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
getVehicle: jest.fn()
|
||||||
|
};
|
||||||
|
store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
vehicles: {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render Vehicle page instance", () => {
|
||||||
|
const wrapper = mount(Vehicle, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
vehicle: () => mockVehicles[0],
|
||||||
|
pilot: () => mockPeople[0],
|
||||||
|
film: () => mockFilms[0]
|
||||||
|
},
|
||||||
|
stubs: ["nuxt-link"]
|
||||||
|
});
|
||||||
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("tests params validation", () => {
|
||||||
|
expect(Vehicle.validate({ params: $route.params })).toBe(true);
|
||||||
|
expect(
|
||||||
|
Vehicle.validate({
|
||||||
|
params: { id: "2baf70d1-42bb-4437-b551-e5fed5a87abe-1234" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
Vehicle.validate({
|
||||||
|
params: { id: "2baf7e0d1-42bb-4437-b551-e5fed5a87abe" }
|
||||||
|
})
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch getVehicle action", async () => {
|
||||||
|
let wrapper = mount(Vehicle, {
|
||||||
|
localVue,
|
||||||
|
store,
|
||||||
|
computed: {
|
||||||
|
vehicle: () => mockVehicles[0],
|
||||||
|
pilot: () => jest.fn(),
|
||||||
|
film: () => jest.fn()
|
||||||
|
},
|
||||||
|
stubs: ["nuxt-link"]
|
||||||
|
});
|
||||||
|
|
||||||
|
await wrapper.vm.$options.asyncData({ store, params: $route.params });
|
||||||
|
expect(actions.getVehicle).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
80
pages/vehicles/_id.vue
Normal file
80
pages/vehicles/_id.vue
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="py-4 flex flex-col lg:flex-row items-center lg:items-start justify-center"
|
||||||
|
>
|
||||||
|
<article
|
||||||
|
class="mb-4 inline-flex flex-col justify-between bg-gray-100 prose prose-sm rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
|
||||||
|
>
|
||||||
|
<header class="p-4 rounded-t-md">
|
||||||
|
<h1>
|
||||||
|
{{ vehicle.name + " (" + vehicle.vehicle_class + ")" }}
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-gray-700 mt-0" v-if="pilot">
|
||||||
|
piloted by
|
||||||
|
<nuxt-link
|
||||||
|
:to="`/people/${pilot.id}`"
|
||||||
|
class="inline-block rounded text-md font-semibold bg-gray-400 py-2 px-4 border-b-4 border-gray-500"
|
||||||
|
>
|
||||||
|
{{ pilot.name }}
|
||||||
|
</nuxt-link>
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="px-4 pb-4 infos">
|
||||||
|
<p>{{ vehicle.description }}</p>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
Appears in
|
||||||
|
</h3>
|
||||||
|
<nuxt-link
|
||||||
|
v-if="film"
|
||||||
|
:to="`/films/${film.id}`"
|
||||||
|
class="inline-block rounded text-md font-semibold bg-gray-400 py-2 px-4 border-b-4 border-gray-500"
|
||||||
|
>
|
||||||
|
{{ film.title }}
|
||||||
|
</nuxt-link>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Vehicle",
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
titleTemplate: `%s - ${this.vehicle.name}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
validate({ params }) {
|
||||||
|
const uuid = new RegExp(
|
||||||
|
/^[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-4[0-9A-Za-z]{3}-[89ABab][0-9A-Za-z]{3}-[0-9A-Za-z]{12}$/
|
||||||
|
);
|
||||||
|
return uuid.test(params.id);
|
||||||
|
},
|
||||||
|
async asyncData({ params, store }) {
|
||||||
|
if (!store.state.vehicles.vehicle.id !== params.id)
|
||||||
|
await store.dispatch("vehicles/getVehicle", params.id);
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pilot: function() {
|
||||||
|
return this.$store.getters["vehicles/getPilot"];
|
||||||
|
},
|
||||||
|
film: function() {
|
||||||
|
return this.$store.getters["vehicles/getFilm"];
|
||||||
|
},
|
||||||
|
...mapGetters({
|
||||||
|
vehicle: "vehicles/vehicle"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
article header {
|
||||||
|
background-color: #85ffbd;
|
||||||
|
background-image: linear-gradient(45deg, #85ffbd 0%, #fffb7d 100%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
7
plugins/README.md
Normal file
7
plugins/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# PLUGINS
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
|
||||||
11
static/README.md
Normal file
11
static/README.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# STATIC
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains your static files.
|
||||||
|
Each file inside this directory is mapped to `/`.
|
||||||
|
Thus you'd want to delete this README.md before deploying to production.
|
||||||
|
|
||||||
|
Example: `/static/robots.txt` is mapped as `/robots.txt`.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
|
||||||
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
10
store/README.md
Normal file
10
store/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# STORE
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains your Vuex Store files.
|
||||||
|
Vuex Store option is implemented in the Nuxt.js framework.
|
||||||
|
|
||||||
|
Creating a file in this directory automatically activates the option in the framework.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
|
||||||
37
store/films/actions.spec.js
Normal file
37
store/films/actions.spec.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { actions } from "./";
|
||||||
|
import axios from "axios";
|
||||||
|
import mockFilms from "@/test/fake-films.json";
|
||||||
|
|
||||||
|
let url = "";
|
||||||
|
|
||||||
|
jest.mock("axios", () => ({
|
||||||
|
$get: _url => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
url = _url;
|
||||||
|
resolve(mockFilms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("Vuex actions.", () => {
|
||||||
|
it("tests films/getList action.", async () => {
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
actions.$axios = axios;
|
||||||
|
await actions.getList({ commit });
|
||||||
|
|
||||||
|
expect(url).toBe(
|
||||||
|
"/api/films?fields=id,title,release_date,director,description,rt_score"
|
||||||
|
);
|
||||||
|
expect(commit).toHaveBeenCalledWith("setList", mockFilms);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("catches errors.", async () => {
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
actions.$axios = null;
|
||||||
|
await expect(actions.getList({ commit })).rejects.toThrow(
|
||||||
|
"API Error occurred: Cannot read property '$get' of null"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
41
store/films/index.js
Normal file
41
store/films/index.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
export const state = () => ({
|
||||||
|
list: [],
|
||||||
|
film: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
setList: (state, films) => {
|
||||||
|
state.list = films;
|
||||||
|
},
|
||||||
|
setFilm: (state, film) => {
|
||||||
|
state.film = film;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
async getList({ commit }) {
|
||||||
|
try {
|
||||||
|
const films = await this.$axios.$get(
|
||||||
|
"/api/films?fields=id,title,release_date,director,description,rt_score"
|
||||||
|
);
|
||||||
|
commit("setList", films);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getFilm({ commit }, id) {
|
||||||
|
try {
|
||||||
|
const film = await this.$axios.$get(
|
||||||
|
`/api/films/${id}?fields=id,title,release_date,director,description,rt_score`
|
||||||
|
);
|
||||||
|
commit("setFilm", film);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
list: state => state.list,
|
||||||
|
film: state => state.film
|
||||||
|
};
|
||||||
9
store/films/mutations.spec.js
Normal file
9
store/films/mutations.spec.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { state, mutations } from "./";
|
||||||
|
import mockFilms from "@/test/fake-films.json";
|
||||||
|
|
||||||
|
describe("Vuex mutations.", () => {
|
||||||
|
it("tests setFilms mutation.", () => {
|
||||||
|
mutations.setList(state, mockFilms);
|
||||||
|
expect(state.list[0].id).toBe(mockFilms[0].id);
|
||||||
|
});
|
||||||
|
});
|
||||||
7
store/index.js
Normal file
7
store/index.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export const state = () => ({});
|
||||||
|
|
||||||
|
export const mutations = {};
|
||||||
|
|
||||||
|
export const actions = {};
|
||||||
|
|
||||||
|
export const getters = {};
|
||||||
44
store/locations/index.js
Normal file
44
store/locations/index.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
export const state = () => ({
|
||||||
|
list: [],
|
||||||
|
location: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
setList: (state, locations) => {
|
||||||
|
state.list = locations;
|
||||||
|
},
|
||||||
|
setLocation: (state, location) => {
|
||||||
|
state.location = location;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
async getList({ commit }) {
|
||||||
|
try {
|
||||||
|
const locations = await this.$axios.$get(
|
||||||
|
"/api/locations?fields=id,name,climate,terrain,surface_water,residents,films"
|
||||||
|
);
|
||||||
|
commit("setList", locations);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getLocation({ commit }, id) {
|
||||||
|
try {
|
||||||
|
const location = await this.$axios.$get(`/api/locations/${id}`);
|
||||||
|
commit("setLocation", location);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
list: state => state.list,
|
||||||
|
location: state => state.location,
|
||||||
|
getLocationsByFilmId: state => id => {
|
||||||
|
return state.list.filter(location =>
|
||||||
|
location.films.find(film => film.split("/")[4] === id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
46
store/people/index.js
Normal file
46
store/people/index.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
export const state = () => ({
|
||||||
|
list: [],
|
||||||
|
person: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
setList: (state, people) => {
|
||||||
|
state.list = people;
|
||||||
|
},
|
||||||
|
setPerson: (state, person) => {
|
||||||
|
state.person = person;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
async getList({ commit }) {
|
||||||
|
try {
|
||||||
|
const people = await this.$axios.$get(
|
||||||
|
"/api/people?fields=id,name,gender,age,eye_color,hair_color,films"
|
||||||
|
);
|
||||||
|
commit("setList", people);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getPerson({ commit }, id) {
|
||||||
|
try {
|
||||||
|
const person = await this.$axios.$get(
|
||||||
|
`/api/people/${id}?fields=id,name,gender,age,eye_color,hair_color,films`
|
||||||
|
);
|
||||||
|
commit("setPerson", person);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
list: state => state.list,
|
||||||
|
person: state => state.person,
|
||||||
|
getPeopleByFilmId: state => id => {
|
||||||
|
return state.list.filter(person =>
|
||||||
|
person.films.find(film => film.split("/")[4] === id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
54
store/vehicles/index.js
Normal file
54
store/vehicles/index.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
export const state = () => ({
|
||||||
|
list: [],
|
||||||
|
vehicle: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
setList: (state, vehicles) => {
|
||||||
|
state.list = vehicles;
|
||||||
|
},
|
||||||
|
setVehicle: (state, vehicle) => {
|
||||||
|
state.vehicle = vehicle;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
async getList({ commit }) {
|
||||||
|
try {
|
||||||
|
const vehicles = await this.$axios.$get(
|
||||||
|
"/api/vehicles?fields=id,name,description,vehicle_class,length,pilot,films"
|
||||||
|
);
|
||||||
|
commit("setList", vehicles);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getVehicle({ commit }, id) {
|
||||||
|
try {
|
||||||
|
const vehicle = await this.$axios.$get(
|
||||||
|
`/api/vehicles/${id}?fields=id,name,description,vehicle_class,length,pilot,films`
|
||||||
|
);
|
||||||
|
commit("setVehicle", vehicle);
|
||||||
|
} catch (e) {
|
||||||
|
throw Error(`API Error occurred: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
list: state => state.list,
|
||||||
|
vehicle: state => state.vehicle,
|
||||||
|
getVehiclesByFilmId: state => id => {
|
||||||
|
return state.list.filter(vehicle => vehicle.films.split("/")[4] === id);
|
||||||
|
},
|
||||||
|
getPilot: (state, getters, rootState) => {
|
||||||
|
return rootState.people.list.find(
|
||||||
|
people => people.id === state.vehicle.pilot.split("/")[4]
|
||||||
|
);
|
||||||
|
},
|
||||||
|
getFilm: (state, getters, rootState) => {
|
||||||
|
return rootState.films.list.find(
|
||||||
|
film => film.id === state.vehicle.films.split("/")[4]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
20
tailwind.config.js
Normal file
20
tailwind.config.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
module.exports = {
|
||||||
|
purge: {
|
||||||
|
enabled: process.env.NODE_ENV === "production",
|
||||||
|
content: [
|
||||||
|
"./components/**/*.{vue,js}",
|
||||||
|
"./layouts/**/*.vue",
|
||||||
|
"./pages/**/*.vue",
|
||||||
|
"./plugins/**/*.{js,ts}",
|
||||||
|
"./nuxt.config.{js,ts}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
darkMode: false,
|
||||||
|
theme: {
|
||||||
|
extend: {}
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
extend: {}
|
||||||
|
},
|
||||||
|
plugins: [require("@tailwindcss/typography")]
|
||||||
|
};
|
||||||
464
test/fake-films.json
Normal file
464
test/fake-films.json
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "2baf70d1-42bb-4437-b551-e5fed5a87abe",
|
||||||
|
"title": "Castle in the Sky",
|
||||||
|
"description": "The orphan Sheeta inherited a mysterious crystal that links her to the mythical sky-kingdom of Laputa. With the help of resourceful Pazu and a rollicking band of sky pirates, she makes her way to the ruins of the once-great civilization. Sheeta and Pazu must outwit the evil Muska, who plans to use Laputa's science to make himself ruler of the world.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Isao Takahata",
|
||||||
|
"release_date": "1986",
|
||||||
|
"rt_score": "95",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "12cfb892-aac0-4c5b-94af-521852e46d6a",
|
||||||
|
"title": "Grave of the Fireflies",
|
||||||
|
"description": "In the latter part of World War II, a boy and his sister, orphaned when their mother is killed in the firebombing of Tokyo, are left to survive on their own in what remains of civilian life in Japan. The plot follows this boy and his sister as they do their best to survive in the Japanese countryside, battling hunger, prejudice, and pride in their own quiet, personal battle.",
|
||||||
|
"director": "Isao Takahata",
|
||||||
|
"producer": "Toru Hara",
|
||||||
|
"release_date": "1988",
|
||||||
|
"rt_score": "97",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/12cfb892-aac0-4c5b-94af-521852e46d6a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "58611129-2dbc-4a81-a72f-77ddfc1b1b49",
|
||||||
|
"title": "My Neighbor Totoro",
|
||||||
|
"description": "Two sisters move to the country with their father in order to be closer to their hospitalized mother, and discover the surrounding trees are inhabited by Totoros, magical spirits of the forest. When the youngest runs away from home, the older sister seeks help from the spirits to find her.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Hayao Miyazaki",
|
||||||
|
"release_date": "1988",
|
||||||
|
"rt_score": "93",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/986faac6-67e3-4fb8-a9ee-bad077c2e7fe",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/d5df3c04-f355-4038-833c-83bd3502b6b9",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/3031caa8-eb1a-41c6-ab93-dd091b541e11",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/87b68b97-3774-495b-bf80-495a5f3e672d",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/d39deecb-2bd0-4770-8b45-485f26e1381f",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/591524bc-04fe-4e60-8d61-2425e42ffb2a",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/c491755a-407d-4d6e-b58a-240ec78b5061",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/f467e18e-3694-409f-bdb3-be891ade1106",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/08ffbce4-7f94-476a-95bc-76d3c3969c19",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/0f8ef701-b4c7-4f15-bd15-368c7fe38d0a"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"https://ghibliapi.herokuapp.com/species/74b7f547-1577-4430-806c-c358c8b6bcf5"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ea660b10-85c4-4ae3-8a5f-41cea3648e3e",
|
||||||
|
"title": "Kiki's Delivery Service",
|
||||||
|
"description": "A young witch, on her mandatory year of independent life, finds fitting into a new community difficult while she supports herself by running an air courier service.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Hayao Miyazaki",
|
||||||
|
"release_date": "1989",
|
||||||
|
"rt_score": "96",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/ea660b10-85c4-4ae3-8a5f-41cea3648e3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4e236f34-b981-41c3-8c65-f8c9000b94e7",
|
||||||
|
"title": "Only Yesterday",
|
||||||
|
"description": "It’s 1982, and Taeko is 27 years old, unmarried, and has lived her whole life in Tokyo. She decides to visit her family in the countryside, and as the train travels through the night, memories flood back of her younger years: the first immature stirrings of romance, the onset of puberty, and the frustrations of math and boys. At the station she is met by young farmer Toshio, and the encounters with him begin to reconnect her to forgotten longings. In lyrical switches between the present and the past, Taeko contemplates the arc of her life, and wonders if she has been true to the dreams of her childhood self.",
|
||||||
|
"director": "Isao Takahata",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "1991",
|
||||||
|
"rt_score": "100",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/4e236f34-b981-41c3-8c65-f8c9000b94e7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ebbb6b7c-945c-41ee-a792-de0e43191bd8",
|
||||||
|
"title": "Porco Rosso",
|
||||||
|
"description": "Porco Rosso, known in Japan as Crimson Pig (Kurenai no Buta) is the sixth animated film by Hayao Miyazaki and released in 1992. You're introduced to an Italian World War I fighter ace, now living as a freelance bounty hunter chasing 'air pirates' in the Adriatic Sea. He has been given a curse that changed his head to that of a pig. Once called Marco Pagot, he is now known to the world as 'Porco Rosso', Italian for 'Red Pig.'",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "1992",
|
||||||
|
"rt_score": "94",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/ebbb6b7c-945c-41ee-a792-de0e43191bd8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1b67aa9a-2e4a-45af-ac98-64d6ad15b16c",
|
||||||
|
"title": "Pom Poko",
|
||||||
|
"description": "As the human city development encroaches on the raccoon population's forest and meadow habitat, the raccoons find themselves faced with the very real possibility of extinction. In response, the raccoons engage in a desperate struggle to stop the construction and preserve their home.",
|
||||||
|
"director": "Isao Takahata",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "1994",
|
||||||
|
"rt_score": "78",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/1b67aa9a-2e4a-45af-ac98-64d6ad15b16c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ff24da26-a969-4f0e-ba1e-a122ead6c6e3",
|
||||||
|
"title": "Whisper of the Heart",
|
||||||
|
"description": "Shizuku lives a simple life, dominated by her love for stories and writing. One day she notices that all the library books she has have been previously checked out by the same person: 'Seiji Amasawa'. Curious as to who he is, Shizuku meets a boy her age whom she finds infuriating, but discovers to her shock that he is her 'Prince of Books'. As she grows closer to him, she realises that he merely read all those books to bring himself closer to her. The boy Seiji aspires to be a violin maker in Italy, and it is his dreams that make Shizuku realise that she has no clear path for her life. Knowing that her strength lies in writing, she tests her talents by writing a story about Baron, a cat statuette belonging to Seiji's grandfather.",
|
||||||
|
"director": "Yoshifumi Kondō",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "1995",
|
||||||
|
"rt_score": "91",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/ff24da26-a969-4f0e-ba1e-a122ead6c6e3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0440483e-ca0e-4120-8c50-4c8cd9b965d6",
|
||||||
|
"title": "Princess Mononoke",
|
||||||
|
"description": "Ashitaka, a prince of the disappearing Ainu tribe, is cursed by a demonized boar god and must journey to the west to find a cure. Along the way, he encounters San, a young human woman fighting to protect the forest, and Lady Eboshi, who is trying to destroy it. Ashitaka must find a way to bring balance to this conflict.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "1997",
|
||||||
|
"rt_score": "92",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/ba924631-068e-4436-b6de-f3283fa848f0",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/ebe40383-aad2-4208-90ab-698f00c581ab",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/030555b3-4c92-4fce-93fb-e70c3ae3df8b",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/ca568e87-4ce2-4afa-a6c5-51f4ae80a60b",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/e9356bb5-4d4a-4c93-aadc-c83e514bffe3",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/34277bec-7401-43fa-a00a-5aee64b45b08",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/91939012-90b9-46e5-a649-96b898073c82",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/20e3bd33-b35d-41e6-83a4-57ca7f028d38",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/8bccdc78-545b-49f4-a4c8-756163a38c91",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/116bfe1b-3ba8-4fa0-8f72-88537a493cb9"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"https://ghibliapi.herokuapp.com/species/6bc92fdd-b0f4-4286-ad71-1f99fb4a0d1e",
|
||||||
|
"https://ghibliapi.herokuapp.com/species/f25fa661-3073-414d-968a-ab062e3065f7"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "45204234-adfd-45cb-a505-a8e7a676b114",
|
||||||
|
"title": "My Neighbors the Yamadas",
|
||||||
|
"description": "The Yamadas are a typical middle class Japanese family in urban Tokyo and this film shows us a variety of episodes of their lives. With tales that range from the humourous to the heartbreaking, we see this family cope with life's little conflicts, problems and joys in their own way.",
|
||||||
|
"director": "Isao Takahata",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "1999",
|
||||||
|
"rt_score": "75",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/45204234-adfd-45cb-a505-a8e7a676b114"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "dc2e6bd1-8156-4886-adff-b39e6043af0c",
|
||||||
|
"title": "Spirited Away",
|
||||||
|
"description": "Spirited Away is an Oscar winning Japanese animated film about a ten year old girl who wanders away from her parents along a path that leads to a world ruled by strange and unusual monster-like animals. Her parents have been changed into pigs along with others inside a bathhouse full of these creatures. Will she ever see the world how it once was?",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2001",
|
||||||
|
"rt_score": "97",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/dc2e6bd1-8156-4886-adff-b39e6043af0c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "90b72513-afd4-4570-84de-a56c312fdf81",
|
||||||
|
"title": "The Cat Returns",
|
||||||
|
"description": "Haru, a schoolgirl bored by her ordinary routine, saves the life of an unusual cat and suddenly her world is transformed beyond anything she ever imagined. The Cat King rewards her good deed with a flurry of presents, including a very shocking proposal of marriage to his son! Haru embarks on an unexpected journey to the Kingdom of Cats where her eyes are opened to a whole other world.",
|
||||||
|
"director": "Hiroyuki Morita",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2002",
|
||||||
|
"rt_score": "89",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cd3d059c-09f4-4ff3-8d63-bc765a5184fa",
|
||||||
|
"title": "Howl's Moving Castle",
|
||||||
|
"description": "When Sophie, a shy young woman, is cursed with an old body by a spiteful witch, her only chance of breaking the spell lies with a self-indulgent yet insecure young wizard and his companions in his legged, walking home.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2004",
|
||||||
|
"rt_score": "87",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/cd3d059c-09f4-4ff3-8d63-bc765a5184fa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "112c1e67-726f-40b1-ac17-6974127bb9b9",
|
||||||
|
"title": "Tales from Earthsea",
|
||||||
|
"description": "Something bizarre has come over the land. The kingdom is deteriorating. People are beginning to act strange... What's even more strange is that people are beginning to see dragons, which shouldn't enter the world of humans. Due to all these bizarre events, Ged, a wandering wizard, is investigating the cause. During his journey, he meets Prince Arren, a young distraught teenage boy. While Arren may look like a shy young teen, he has a severe dark side, which grants him strength, hatred, ruthlessness and has no mercy, especially when it comes to protecting Teru. For the witch Kumo this is a perfect opportunity. She can use the boy's 'fears' against the very one who would help him, Ged.",
|
||||||
|
"director": "Gorō Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2006",
|
||||||
|
"rt_score": "41",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/112c1e67-726f-40b1-ac17-6974127bb9b9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "758bf02e-3122-46e0-884e-67cf83df1786",
|
||||||
|
"title": "Ponyo",
|
||||||
|
"description": "The son of a sailor, 5-year old Sosuke lives a quiet life on an oceanside cliff with his mother Lisa. One fateful day, he finds a beautiful goldfish trapped in a bottle on the beach and upon rescuing her, names her Ponyo. But she is no ordinary goldfish. The daughter of a masterful wizard and a sea goddess, Ponyo uses her father's magic to transform herself into a young girl and quickly falls in love with Sosuke, but the use of such powerful sorcery causes a dangerous imbalance in the world. As the moon steadily draws nearer to the earth and Ponyo's father sends the ocean's mighty waves to find his daughter, the two children embark on an adventure of a lifetime to save the world and fulfill Ponyo's dreams of becoming human.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2008",
|
||||||
|
"rt_score": "92",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/758bf02e-3122-46e0-884e-67cf83df1786"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2de9426b-914a-4a06-a3a0-5e6d9d3886f6",
|
||||||
|
"title": "Arrietty",
|
||||||
|
"description": "14-year-old Arrietty and the rest of the Clock family live in peaceful anonymity as they make their own home from items 'borrowed' from the house's human inhabitants. However, life changes for the Clocks when a human boy discovers Arrietty.",
|
||||||
|
"director": "Hiromasa Yonebayashi",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2010",
|
||||||
|
"rt_score": "95",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/2de9426b-914a-4a06-a3a0-5e6d9d3886f6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "45db04e4-304a-4933-9823-33f389e8d74d",
|
||||||
|
"title": "From Up on Poppy Hill",
|
||||||
|
"description": "The story is set in 1963 in Yokohama. Kokuriko Manor sits on a hill overlooking the harbour. A 16 year-old girl, Umi, lives in that house. Every morning she raises a signal flag facing the sea. The flag means “I pray for safe voyages”. A 17 year-old boy, Shun, always sees this flag from the sea as he rides a tugboat to school. Gradually the pair are drawn to each other but they are faced with a sudden trial. Even so, they keep going without running from facing the hardships of reality.",
|
||||||
|
"director": "Gorō Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2011",
|
||||||
|
"rt_score": "83",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/45db04e4-304a-4933-9823-33f389e8d74d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "67405111-37a5-438f-81cc-4666af60c800",
|
||||||
|
"title": "The Wind Rises",
|
||||||
|
"description": "A lifelong love of flight inspires Japanese aviation engineer Jiro Horikoshi, whose storied career includes the creation of the A-6M World War II fighter plane.",
|
||||||
|
"director": "Hayao Miyazaki",
|
||||||
|
"producer": "Toshio Suzuki",
|
||||||
|
"release_date": "2013",
|
||||||
|
"rt_score": "89",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/67405111-37a5-438f-81cc-4666af60c800"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "578ae244-7750-4d9f-867b-f3cd3d6fecf4",
|
||||||
|
"title": "The Tale of the Princess Kaguya",
|
||||||
|
"description": "A bamboo cutter named Sanuki no Miyatsuko discovers a miniature girl inside a glowing bamboo shoot. Believing her to be a divine presence, he and his wife decide to raise her as their own, calling her 'Princess'.",
|
||||||
|
"director": "Isao Takahata",
|
||||||
|
"producer": "Yoshiaki Nishimura",
|
||||||
|
"release_date": "2013",
|
||||||
|
"rt_score": "100",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/578ae244-7750-4d9f-867b-f3cd3d6fecf4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5fdfb320-2a02-49a7-94ff-5ca418cae602",
|
||||||
|
"title": "When Marnie Was There",
|
||||||
|
"description": "The film follows Anna Sasaki living with her relatives in the seaside town. Anna comes across a nearby abandoned mansion, where she meets Marnie, a mysterious girl who asks her to promise to keep their secrets from everyone. As the summer progresses, Anna spends more time with Marnie, and eventually Anna learns the truth about her family and foster care.",
|
||||||
|
"director": "Hiromasa Yonebayashi",
|
||||||
|
"producer": "Yoshiaki Nishimura",
|
||||||
|
"release_date": "2014",
|
||||||
|
"rt_score": "92",
|
||||||
|
"people": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/"
|
||||||
|
],
|
||||||
|
"species": [
|
||||||
|
"https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2"
|
||||||
|
],
|
||||||
|
"locations": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/"
|
||||||
|
],
|
||||||
|
"vehicles": [
|
||||||
|
"https://ghibliapi.herokuapp.com/vehicles/"
|
||||||
|
],
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/films/5fdfb320-2a02-49a7-94ff-5ca418cae602"
|
||||||
|
}
|
||||||
|
]
|
||||||
391
test/fake-locations.json
Normal file
391
test/fake-locations.json
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "11014596-71b0-4b3e-b8c0-1c4b15f28b9a",
|
||||||
|
"name": "Irontown",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "Mountain",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/ba924631-068e-4436-b6de-f3283fa848f0",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/030555b3-4c92-4fce-93fb-e70c3ae3df8b"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/11014596-71b0-4b3e-b8c0-1c4b15f28b9a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "64a996aa-481e-4627-9624-ab23f59a05a9",
|
||||||
|
"name": "Gutiokipanja",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "Hill",
|
||||||
|
"surface_water": "50",
|
||||||
|
"residents": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/ba924631-068e-4436-b6de-f3283fa848f0",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/030555b3-4c92-4fce-93fb-e70c3ae3df8b"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/64a996aa-481e-4627-9624-ab23f59a05a9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a8bd9c03-7c80-4a97-b7c0-6a668acaf576",
|
||||||
|
"name": "The Cat Kingdom",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "Plain",
|
||||||
|
"surface_water": "30",
|
||||||
|
"residents": [
|
||||||
|
"https://ghibliapi.herokuapp.com/people/6b3facea-ea33-47b1-96ce-3fc737b119b8",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/3042818d-a8bb-4cba-8180-c19249822d57",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/58d1973f-f247-47d7-9358-e56cb0d2b5a6",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/a3d8e70f-46a0-4e5a-b850-db01620d6b92",
|
||||||
|
"https://ghibliapi.herokuapp.com/people/fc196c4f-0201-4ed2-9add-c6403f7c4d32"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/a8bd9c03-7c80-4a97-b7c0-6a668acaf576"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "56e423c4-d9a1-44c4-8bdb-1cab45fbf63e",
|
||||||
|
"name": "The Marsh House",
|
||||||
|
"climate": "Mild",
|
||||||
|
"terrain": "Marsh",
|
||||||
|
"surface_water": "60",
|
||||||
|
"residents": [],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/5fdfb320-2a02-49a7-94ff-5ca418cae602"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/56e423c4-d9a1-44c4-8bdb-1cab45fbf63e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "660c8c91-bd92-43db-b475-b2df6ca96fec",
|
||||||
|
"name": "Hospital",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "Hill",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/660c8c91-bd92-43db-b475-b2df6ca96fec"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6ba60a86-7c74-4ec4-a6f4-7112b5705a2f",
|
||||||
|
"name": "Gondoa",
|
||||||
|
"climate": "TODO",
|
||||||
|
"terrain": "TODO",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/6ba60a86-7c74-4ec4-a6f4-7112b5705a2f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fb083a4e-77b2-4623-a2e0-6bbca5bfd5b2",
|
||||||
|
"name": "Ursula's Log Cabin",
|
||||||
|
"climate": "TODO",
|
||||||
|
"terrain": "TODO",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ea660b10-85c4-4ae3-8a5f-41cea3648e3e"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/fb083a4e-77b2-4623-a2e0-6bbca5bfd5b2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a072ec53-0467-4fac-864f-df234f9c4315",
|
||||||
|
"name": "Zeniba's Cottage",
|
||||||
|
"climate": "TODO",
|
||||||
|
"terrain": "TODO",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/dc2e6bd1-8156-4886-adff-b39e6043af0c"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/a072ec53-0467-4fac-864f-df234f9c4315"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "682df5c3-b09e-46af-94d1-ae0d17f9b4b6",
|
||||||
|
"name": "Bamboo Forest",
|
||||||
|
"climate": "Tropical",
|
||||||
|
"terrain": "Forest",
|
||||||
|
"surface_water": "10",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/45204234-adfd-45cb-a505-a8e7a676b114",
|
||||||
|
"https://ghibliapi.herokuapp.com/films/578ae244-7750-4d9f-867b-f3cd3d6fecf4"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/682df5c3-b09e-46af-94d1-ae0d17f9b4b6"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "26361a2c-32c6-4bd5-ae9c-8e40e17ae28d",
|
||||||
|
"name": "Pazu's Mines",
|
||||||
|
"climate": "Dry",
|
||||||
|
"terrain": "Hill",
|
||||||
|
"surface_water": "0",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/26361a2c-32c6-4bd5-ae9c-8e40e17ae28d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "42f787d8-1fcb-4d3d-82f2-a74409869368",
|
||||||
|
"name": "Shizuku's Apartment",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "City",
|
||||||
|
"surface_water": "0",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ff24da26-a969-4f0e-ba1e-a122ead6c6e3"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/42f787d8-1fcb-4d3d-82f2-a74409869368"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0fafa7a3-64c1-43fe-881b-ecb605c01e09",
|
||||||
|
"name": "Laputa",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "City",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/0fafa7a3-64c1-43fe-881b-ecb605c01e09"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0132f7f6-fd52-4ac3-b5df-c96b609f77b6",
|
||||||
|
"name": "Tedis",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "Hill",
|
||||||
|
"surface_water": "30",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/0132f7f6-fd52-4ac3-b5df-c96b609f77b6"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c57fb2cb-ea85-4d73-8808-cf5dcd28c22e",
|
||||||
|
"name": "Koriko",
|
||||||
|
"climate": "Mild",
|
||||||
|
"terrain": "Hill",
|
||||||
|
"surface_water": "50",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ea660b10-85c4-4ae3-8a5f-41cea3648e3e"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/c57fb2cb-ea85-4d73-8808-cf5dcd28c22e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "615aa48d-8673-4117-b35a-79cb67af1897",
|
||||||
|
"name": "Forest",
|
||||||
|
"climate": "Tropical",
|
||||||
|
"terrain": "Forest",
|
||||||
|
"surface_water": "60",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/615aa48d-8673-4117-b35a-79cb67af1897"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "37d13a96-a03a-451d-8871-80be0495486e",
|
||||||
|
"name": "Bathhouse",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "River",
|
||||||
|
"surface_water": "70",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/dc2e6bd1-8156-4886-adff-b39e6043af0c"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/37d13a96-a03a-451d-8871-80be0495486e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6fc21b76-78fb-4451-98f7-857e32a23e85",
|
||||||
|
"name": "Matsugo",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "River",
|
||||||
|
"surface_water": "60",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/6fc21b76-78fb-4451-98f7-857e32a23e85"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "dbeeaecb-7817-4b8b-90ca-edc432d3033e",
|
||||||
|
"name": "Taeko's House",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "River",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/4e236f34-b981-41c3-8c65-f8c9000b94e7"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/dbeeaecb-7817-4b8b-90ca-edc432d3033e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "34df8f25-8f80-4823-8f01-bf9852039987",
|
||||||
|
"name": "Piccolo S.P.A.",
|
||||||
|
"climate": "Continental",
|
||||||
|
"terrain": "River",
|
||||||
|
"surface_water": "40",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ebbb6b7c-945c-41ee-a792-de0e43191bd8"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/34df8f25-8f80-4823-8f01-bf9852039987"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "62346d33-caa0-4c17-8016-0aca56f3066b",
|
||||||
|
"name": "Karikiya",
|
||||||
|
"climate": "Mild",
|
||||||
|
"terrain": "City",
|
||||||
|
"surface_water": "30",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ea660b10-85c4-4ae3-8a5f-41cea3648e3e"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/62346d33-caa0-4c17-8016-0aca56f3066b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ee897b2a-405e-42b9-bff4-8b51b0f03cab",
|
||||||
|
"name": "Satsuki's School House",
|
||||||
|
"climate": "Mild",
|
||||||
|
"terrain": "River",
|
||||||
|
"surface_water": "60",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/ee897b2a-405e-42b9-bff4-8b51b0f03cab"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "90241c46-d4be-411f-b00a-7561b9dda7b6",
|
||||||
|
"name": "Fujimoto's Underwater Harbor",
|
||||||
|
"climate": "Wet",
|
||||||
|
"terrain": "Ocean",
|
||||||
|
"surface_water": "100",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/758bf02e-3122-46e0-884e-67cf83df1786"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/90241c46-d4be-411f-b00a-7561b9dda7b6"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "469b14bd-5565-4436-bbed-c2036f42cc99",
|
||||||
|
"name": "Himawari Nursery School",
|
||||||
|
"climate": "Mild",
|
||||||
|
"terrain": "Ocean",
|
||||||
|
"surface_water": "50",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/758bf02e-3122-46e0-884e-67cf83df1786"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/469b14bd-5565-4436-bbed-c2036f42cc99"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b6bac992-a858-4d57-8477-9652d73caaa1",
|
||||||
|
"name": "Ingary",
|
||||||
|
"climate": "Mild",
|
||||||
|
"terrain": "Hill",
|
||||||
|
"surface_water": "30",
|
||||||
|
"residents": [
|
||||||
|
"TODO"
|
||||||
|
],
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/cd3d059c-09f4-4ff3-8d63-bc765a5184fa"
|
||||||
|
],
|
||||||
|
"url": [
|
||||||
|
"https://ghibliapi.herokuapp.com/locations/b6bac992-a858-4d57-8477-9652d73caaa1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
563
test/fake-people.json
Normal file
563
test/fake-people.json
Normal file
@@ -0,0 +1,563 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "fe93adf2-2f3a-4ec4-9f68-5422f1b87c01",
|
||||||
|
"name": "Pazu",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "13",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/fe93adf2-2f3a-4ec4-9f68-5422f1b87c01"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "598f7048-74ff-41e0-92ef-87dc1ad980a9",
|
||||||
|
"name": "Lusheeta Toel Ul Laputa",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "13",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Black",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/598f7048-74ff-41e0-92ef-87dc1ad980a9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3bc0b41e-3569-4d20-ae73-2da329bf0786",
|
||||||
|
"name": "Dola",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "60",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Peach",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/3bc0b41e-3569-4d20-ae73-2da329bf0786"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "abe886e7-30c8-4c19-aaa5-d666e60d14de",
|
||||||
|
"name": "Romska Palo Ul Laputa",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "33",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/abe886e7-30c8-4c19-aaa5-d666e60d14de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e08880d0-6938-44f3-b179-81947e7873fc",
|
||||||
|
"name": "Uncle Pom",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Unspecified/Elderly",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "White",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/e08880d0-6938-44f3-b179-81947e7873fc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5c83c12a-62d5-4e92-8672-33ac76ae1fa0",
|
||||||
|
"name": "General Muoro",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Unspecified/Adult",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "None",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/5c83c12a-62d5-4e92-8672-33ac76ae1fa0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3f4c408b-0bcc-45a0-bc8b-20ffc67a2ede",
|
||||||
|
"name": "Duffi",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Unspecified/Adult",
|
||||||
|
"eye_color": "Dark brown",
|
||||||
|
"hair_color": "Dark brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/3f4c408b-0bcc-45a0-bc8b-20ffc67a2ede"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fcb4a2ac-5e41-4d54-9bba-33068db083ca",
|
||||||
|
"name": "Louis",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "30",
|
||||||
|
"eye_color": "Dark brown",
|
||||||
|
"hair_color": "Dark brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/fcb4a2ac-5e41-4d54-9bba-33068db083ca"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2cb76c15-772a-4cb3-9919-3652f56611d0",
|
||||||
|
"name": "Charles",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Unspecified/Adult",
|
||||||
|
"eye_color": "Dark brown",
|
||||||
|
"hair_color": "Light brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/2cb76c15-772a-4cb3-9919-3652f56611d0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f6f2c477-98aa-4796-b9aa-8209fdeed6b9",
|
||||||
|
"name": "Henri",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Unspecified/Adult",
|
||||||
|
"eye_color": "Dark brown",
|
||||||
|
"hair_color": "Reddish brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/f6f2c477-98aa-4796-b9aa-8209fdeed6b9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "05d8d01b-0c2f-450e-9c55-aa0daa34838e",
|
||||||
|
"name": "Motro",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Unspecified/Adult",
|
||||||
|
"eye_color": "Dark brown",
|
||||||
|
"hair_color": "None",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/05d8d01b-0c2f-450e-9c55-aa0daa34838e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b22a684f-1819-40c8-94a6-d40c3b5e18eb",
|
||||||
|
"name": "Okami",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "50",
|
||||||
|
"eye_color": "Dark brown",
|
||||||
|
"hair_color": "Orange",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/b22a684f-1819-40c8-94a6-d40c3b5e18eb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ba924631-068e-4436-b6de-f3283fa848f0",
|
||||||
|
"name": "Ashitaka",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "late teens",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/ba924631-068e-4436-b6de-f3283fa848f0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ebe40383-aad2-4208-90ab-698f00c581ab",
|
||||||
|
"name": "San",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "17",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/ebe40383-aad2-4208-90ab-698f00c581ab"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "34277bec-7401-43fa-a00a-5aee64b45b08",
|
||||||
|
"name": "Eboshi",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "Unspecified/Adult",
|
||||||
|
"eye_color": "Hazel",
|
||||||
|
"hair_color": "Black",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/34277bec-7401-43fa-a00a-5aee64b45b08"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "91939012-90b9-46e5-a649-96b898073c82",
|
||||||
|
"name": "Jigo",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Middle age",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/91939012-90b9-46e5-a649-96b898073c82"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "20e3bd33-b35d-41e6-83a4-57ca7f028d38",
|
||||||
|
"name": "Kohroku",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Adult",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/20e3bd33-b35d-41e6-83a4-57ca7f028d38"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8bccdc78-545b-49f4-a4c8-756163a38c91",
|
||||||
|
"name": "Gonza",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "Adult",
|
||||||
|
"eye_color": "Grey",
|
||||||
|
"hair_color": "Bald, but beard is Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/8bccdc78-545b-49f4-a4c8-756163a38c91"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "116bfe1b-3ba8-4fa0-8f72-88537a493cb9",
|
||||||
|
"name": "Hii-sama",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "Over 50",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "White",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/116bfe1b-3ba8-4fa0-8f72-88537a493cb9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "030555b3-4c92-4fce-93fb-e70c3ae3df8b",
|
||||||
|
"name": "Yakul",
|
||||||
|
"age": "Unknown",
|
||||||
|
"gender": "Male",
|
||||||
|
"eye_color": "Grey",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/6bc92fdd-b0f4-4286-ad71-1f99fb4a0d1e",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/030555b3-4c92-4fce-93fb-e70c3ae3df8b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ca568e87-4ce2-4afa-a6c5-51f4ae80a60b",
|
||||||
|
"name": "Shishigami",
|
||||||
|
"age": "400",
|
||||||
|
"gender": "Male",
|
||||||
|
"eye_color": "Red",
|
||||||
|
"hair_color": "Light Orange",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/6bc92fdd-b0f4-4286-ad71-1f99fb4a0d1e",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/ca568e87-4ce2-4afa-a6c5-51f4ae80a60b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e9356bb5-4d4a-4c93-aadc-c83e514bffe3",
|
||||||
|
"name": "Moro",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "300",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "White",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/0440483e-ca0e-4120-8c50-4c8cd9b965d6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/f25fa661-3073-414d-968a-ab062e3065f7",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/e9356bb5-4d4a-4c93-aadc-c83e514bffe3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7151abc6-1a9e-4e6a-9711-ddb50ea572ec",
|
||||||
|
"name": "Jiji",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Black",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ea660b10-85c4-4ae3-8a5f-41cea3648e3e"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/7151abc6-1a9e-4e6a-9711-ddb50ea572ec"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "986faac6-67e3-4fb8-a9ee-bad077c2e7fe",
|
||||||
|
"name": "Satsuki Kusakabe",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "11",
|
||||||
|
"eye_color": "Dark Brown/Black",
|
||||||
|
"hair_color": "Dark Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/986faac6-67e3-4fb8-a9ee-bad077c2e7fe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d5df3c04-f355-4038-833c-83bd3502b6b9",
|
||||||
|
"name": "Mei Kusakabe",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "4",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Light Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/d5df3c04-f355-4038-833c-83bd3502b6b9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3031caa8-eb1a-41c6-ab93-dd091b541e11",
|
||||||
|
"name": "Tatsuo Kusakabe",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "37",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Dark Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/3031caa8-eb1a-41c6-ab93-dd091b541e11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "87b68b97-3774-495b-bf80-495a5f3e672d",
|
||||||
|
"name": "Yasuko Kusakabe",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "Adult",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Dark Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/87b68b97-3774-495b-bf80-495a5f3e672d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "08ffbce4-7f94-476a-95bc-76d3c3969c19",
|
||||||
|
"name": "Granny",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "Elder",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Grey",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/08ffbce4-7f94-476a-95bc-76d3c3969c19"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0f8ef701-b4c7-4f15-bd15-368c7fe38d0a",
|
||||||
|
"name": "Kanta Ogaki",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "11",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/0f8ef701-b4c7-4f15-bd15-368c7fe38d0a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d39deecb-2bd0-4770-8b45-485f26e1381f",
|
||||||
|
"name": "Totoro",
|
||||||
|
"gender": "NA",
|
||||||
|
"age": "",
|
||||||
|
"eye_color": "Grey",
|
||||||
|
"hair_color": "Grey",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/74b7f547-1577-4430-806c-c358c8b6bcf5",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/d39deecb-2bd0-4770-8b45-485f26e1381f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "591524bc-04fe-4e60-8d61-2425e42ffb2a",
|
||||||
|
"name": "Chu Totoro",
|
||||||
|
"gender": "NA",
|
||||||
|
"age": "",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Blue",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/74b7f547-1577-4430-806c-c358c8b6bcf5",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/d39deecb-2bd0-4770-8b45-485f26e1381f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c491755a-407d-4d6e-b58a-240ec78b5061",
|
||||||
|
"name": "Chibi Totoro",
|
||||||
|
"gender": "NA",
|
||||||
|
"age": "",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "White",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/74b7f547-1577-4430-806c-c358c8b6bcf5",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/d39deecb-2bd0-4770-8b45-485f26e1381f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f467e18e-3694-409f-bdb3-be891ade1106",
|
||||||
|
"name": "Catbus",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "Yellow",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/f467e18e-3694-409f-bdb3-be891ade1106"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "89026b3a-abc4-4053-ab1a-c6d2eea68faa",
|
||||||
|
"name": "Niya",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "White",
|
||||||
|
"hair_color": "Beige",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2de9426b-914a-4a06-a3a0-5e6d9d3886f6"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/89026b3a-abc4-4053-ab1a-c6d2eea68faa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6b3facea-ea33-47b1-96ce-3fc737b119b8",
|
||||||
|
"name": "Renaldo Moon aka Moon aka Muta",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "White",
|
||||||
|
"hair_color": "Beige",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81",
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ff24da26-a969-4f0e-ba1e-a122ead6c6e3"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/6b3facea-ea33-47b1-96ce-3fc737b119b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3042818d-a8bb-4cba-8180-c19249822d57",
|
||||||
|
"name": "Cat King",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "87",
|
||||||
|
"eye_color": "Emerald",
|
||||||
|
"hair_color": "Grey",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/3042818d-a8bb-4cba-8180-c19249822d57"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "58d1973f-f247-47d7-9358-e56cb0d2b5a6",
|
||||||
|
"name": "Yuki",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "Blue",
|
||||||
|
"hair_color": "White",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/58d1973f-f247-47d7-9358-e56cb0d2b5a6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a3d8e70f-46a0-4e5a-b850-db01620d6b92",
|
||||||
|
"name": "Haru",
|
||||||
|
"gender": "Female",
|
||||||
|
"age": "13",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/a3d8e70f-46a0-4e5a-b850-db01620d6b92"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fc196c4f-0201-4ed2-9add-c6403f7c4d32",
|
||||||
|
"name": "Baron Humbert von Gikkingen",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "Green",
|
||||||
|
"hair_color": "Yellow",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ff24da26-a969-4f0e-ba1e-a122ead6c6e3",
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/fc196c4f-0201-4ed2-9add-c6403f7c4d32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "466bc926-2024-4653-ac63-fe52f2dc8c7b",
|
||||||
|
"name": "Natori",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "NA",
|
||||||
|
"eye_color": "Blue",
|
||||||
|
"hair_color": "Grey",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/90b72513-afd4-4570-84de-a56c312fdf81"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/603428ba-8a86-4b0b-a9f1-65df6abef3d3",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/466bc926-2024-4653-ac63-fe52f2dc8c7b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "40c005ce-3725-4f15-8409-3e1b1b14b583",
|
||||||
|
"name": "Colonel Muska",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "33",
|
||||||
|
"eye_color": "Grey",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/40c005ce-3725-4f15-8409-3e1b1b14b583"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6523068d-f5a9-4150-bf5b-76abe6fb42c3",
|
||||||
|
"name": "Porco Rosso",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "47",
|
||||||
|
"eye_color": "Black",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/ebbb6b7c-945c-41ee-a792-de0e43191bd8"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/6523068d-f5a9-4150-bf5b-76abe6fb42c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a10f64f3-e0b6-4a94-bf30-87ad8bc51607",
|
||||||
|
"name": "Sosuke",
|
||||||
|
"gender": "Male",
|
||||||
|
"age": "5",
|
||||||
|
"eye_color": "Brown",
|
||||||
|
"hair_color": "Brown",
|
||||||
|
"films": [
|
||||||
|
"https://ghibliapi.herokuapp.com/films/758bf02e-3122-46e0-884e-67cf83df1786"
|
||||||
|
],
|
||||||
|
"species": "https://ghibliapi.herokuapp.com/species/af3910a6-429f-4c74-9ad5-dfe1c4aa04f2",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/people/a10f64f3-e0b6-4a94-bf30-87ad8bc51607"
|
||||||
|
}
|
||||||
|
]
|
||||||
32
test/fake-vehicles.json
Normal file
32
test/fake-vehicles.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "4e09b023-f650-4747-9ab9-eacf14540cfb",
|
||||||
|
"name": "Air Destroyer Goliath",
|
||||||
|
"description": "A military airship utilized by the government to access Laputa",
|
||||||
|
"vehicle_class": "Airship",
|
||||||
|
"length": "1,000",
|
||||||
|
"pilot": "https://ghibliapi.herokuapp.com/people/40c005ce-3725-4f15-8409-3e1b1b14b583",
|
||||||
|
"films": "https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/vehicles/4e09b023-f650-4747-9ab9-eacf14540cfb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d8f893b5-1dd9-41a1-9918-0099c1aa2de8",
|
||||||
|
"name": "Red Wing",
|
||||||
|
"description": "An experimental aircraft captured by Porco. Named Savoia S.21",
|
||||||
|
"vehicle_class": "Airplane",
|
||||||
|
"length": "20",
|
||||||
|
"pilot": "https://ghibliapi.herokuapp.com/people/6523068d-f5a9-4150-bf5b-76abe6fb42c3",
|
||||||
|
"films": "https://ghibliapi.herokuapp.com/films/ebbb6b7c-945c-41ee-a792-de0e43191bd8",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/vehicles/d8f893b5-1dd9-41a1-9918-0099c1aa2de8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "923d70c9-8f15-4972-ad53-0128b261d628",
|
||||||
|
"name": "Sosuke's Boat",
|
||||||
|
"description": "A toy boat where Sosuke plays",
|
||||||
|
"vehicle_class": "Boat",
|
||||||
|
"length": "10",
|
||||||
|
"pilot": "https://ghibliapi.herokuapp.com/people/a10f64f3-e0b6-4a94-bf30-87ad8bc51607",
|
||||||
|
"films": "https://ghibliapi.herokuapp.com/films/758bf02e-3122-46e0-884e-67cf83df1786",
|
||||||
|
"url": "https://ghibliapi.herokuapp.com/vehicles/923d70c9-8f15-4972-ad53-0128b261d628"
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user