Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API失敗時のテストコード: apiモジュールの再編 #119

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c8f2b28
add: API失敗時のテストコード: `PrefectureMasterApi`を作成
YuukiToriyama Jan 7, 2024
ab5a453
update: API失敗時のテストコード: `PrefectureMasterApi.get()`を実装
YuukiToriyama Jan 7, 2024
ed6e5a2
update: API失敗時のテストコード: `PrefectureMasterApi.get_blocking()`を実装
YuukiToriyama Jan 7, 2024
5186167
add: API失敗時のテストコード: `CityMasterApi`を作成
YuukiToriyama Jan 7, 2024
8a9f549
update: API失敗時のテストコード: `CityMasterApi.get()`を実装
YuukiToriyama Jan 7, 2024
1720a21
update: API失敗時のテストコード: `CityMasterApi.get_blocking()`を実装
YuukiToriyama Jan 7, 2024
77d9f96
update: API失敗時のテストコード: `PrefectureMasterApi`に対するテストコードを追加
YuukiToriyama Jan 7, 2024
cd452fb
update: API失敗時のテストコード: `CityMasterApi`に対するテストコードを追加
YuukiToriyama Jan 7, 2024
48df1db
update: API失敗時のテストコード: `prefecture_master_api`と`city_master_api`をそれぞれ…
YuukiToriyama Jan 7, 2024
870d915
update: API失敗時のテストコード: `PrefectureMasterApi`,`CityMasterApi`のそれぞれに定義し…
YuukiToriyama Jan 7, 2024
7c62232
update: API失敗時のテストコード: `CityMasterApi.server_url`をpublicに変更
YuukiToriyama Jan 10, 2024
c4c762f
update: API失敗時のテストコード: `PrefectureMasterApi.server_url`をpublicに変更
YuukiToriyama Jan 10, 2024
ad12d5e
add: API失敗時のテストコード: `api::ApiImpl`を実装
YuukiToriyama Jan 10, 2024
10d9aa7
add: API失敗時のテストコード: `api::BlockingApiImpl`を実装
YuukiToriyama Jan 10, 2024
09b1807
update: API失敗時のテストコード: `api::ApiImpl`のメンバとしてPrefectureMasterApiとCityM…
YuukiToriyama Jan 10, 2024
6000493
update: API失敗時のテストコード: `api::BlockingApiImpl`のメンバとしてPrefectureMasterA…
YuukiToriyama Jan 10, 2024
57888be
update: API失敗時のテストコード: `api::client::ApiImpl`を使用していた箇所を`api::ApiImpl`に変更
YuukiToriyama Jan 10, 2024
6ddca02
update: API失敗時のテストコード: `api::blocking::Client`を使用していた箇所を`api::Blockin…
YuukiToriyama Jan 10, 2024
16f4ce1
delete: API失敗時のテストコード: `api/client.rs`, `api/blocking.rs`を削除
YuukiToriyama Jan 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 69 additions & 3 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#[cfg(not(target_arch = "wasm32"))]
pub mod blocking;
pub mod client;
pub mod city_master_api;
pub mod prefecture_master_api;

use crate::api::city_master_api::CityMasterApi;
use crate::api::prefecture_master_api::PrefectureMasterApi;
use crate::entity::{City, Prefecture};
use crate::err::Error;
use std::future::Future;

pub trait Api {
fn new() -> Self;
fn get_prefecture_master(
&self,
prefecture_name: &str,
Expand All @@ -18,7 +20,71 @@ pub trait Api {
) -> impl Future<Output = Result<City, Error>>;
}

pub struct ApiImpl {
prefecture_master_api: PrefectureMasterApi,
city_master_api: CityMasterApi,
}

impl Api for ApiImpl {
fn new() -> Self {
ApiImpl {
prefecture_master_api: PrefectureMasterApi {
server_url:
"https://yuukitoriyama.github.io/geolonia-japanese-addresses-accompanist",
},
city_master_api: CityMasterApi {
server_url: "https://geolonia.github.io/japanese-addresses/api/ja",
},
}
}

fn get_prefecture_master(
&self,
prefecture_name: &str,
) -> impl Future<Output = Result<Prefecture, Error>> {
self.prefecture_master_api.get(prefecture_name)
}

fn get_city_master(
&self,
prefecture_name: &str,
city_name: &str,
) -> impl Future<Output = Result<City, Error>> {
self.city_master_api.get(prefecture_name, city_name)
}
}

#[cfg(not(target_arch = "wasm32"))]
pub trait BlockingApi {
fn new() -> Self;
fn get_prefecture_master(&self, prefecture_name: &str) -> Result<Prefecture, Error>;
fn get_city_master(&self, prefecture_name: &str, city_name: &str) -> Result<City, Error>;
}

#[cfg(not(target_arch = "wasm32"))]
pub struct BlockingApiImpl {
prefecture_master_api: PrefectureMasterApi,
city_master_api: CityMasterApi,
}

#[cfg(not(target_arch = "wasm32"))]
impl BlockingApi for BlockingApiImpl {
fn new() -> Self {
BlockingApiImpl {
prefecture_master_api: PrefectureMasterApi {
server_url: "https://yuukitoriyama.github.io/geolonia-japanese-addresses-accompanist",
},
city_master_api: CityMasterApi {
server_url: "https://geolonia.github.io/japanese-addresses/api/ja",
},
}
}

fn get_prefecture_master(&self, prefecture_name: &str) -> Result<Prefecture, Error> {
self.prefecture_master_api.get_blocking(prefecture_name)
}

fn get_city_master(&self, prefecture_name: &str, city_name: &str) -> Result<City, Error> {
self.city_master_api.get_blocking(prefecture_name, city_name)
}
}
115 changes: 0 additions & 115 deletions src/api/blocking.rs

This file was deleted.

120 changes: 120 additions & 0 deletions src/api/city_master_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use crate::entity::{City, Town};
use crate::err::{ApiErrorKind, Error};

pub struct CityMasterApi {
pub server_url: &'static str,
}

impl CityMasterApi {
pub async fn get(&self, prefecture_name: &str, city_name: &str) -> Result<City, Error> {
let endpoint = format!("{}/{}/{}.json", self.server_url, prefecture_name, city_name);
let response = match reqwest::get(&endpoint).await {
Ok(result) => result,
Err(_) => return Err(Error::new_api_error(ApiErrorKind::Deserialize(endpoint))),
};
if response.status() == 200 {
match response.json::<Vec<Town>>().await {
Ok(result) => Ok(City {
name: city_name.to_string(),
towns: result,
}),
Err(_) => Err(Error::new_api_error(ApiErrorKind::Deserialize(endpoint))),
}
} else {
Err(Error::new_api_error(ApiErrorKind::Fetch(endpoint)))
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn get_blocking(&self, prefecture_name: &str, city_name: &str) -> Result<City, Error> {
let endpoint = format!("{}/{}/{}.json", self.server_url, prefecture_name, city_name);
let response = match reqwest::blocking::get(&endpoint) {
Ok(result) => result,
Err(_) => return Err(Error::new_api_error(ApiErrorKind::Fetch(endpoint))),
};
if response.status() == 200 {
match response.json::<Vec<Town>>() {
Ok(result) => Ok(City {
name: city_name.to_string(),
towns: result,
}),
Err(_) => Err(Error::new_api_error(ApiErrorKind::Deserialize(endpoint))),
}
} else {
Err(Error::new_api_error(ApiErrorKind::Fetch(endpoint)))
}
}
}

#[cfg(test)]
mod tests {
use crate::api::city_master_api::CityMasterApi;
use crate::entity::Town;

#[tokio::test]
async fn 非同期_石川県羽咋郡志賀町_成功() {
let city_master_api = CityMasterApi {
server_url: "https://geolonia.github.io/japanese-addresses/api/ja",
};
let result = city_master_api.get("石川県", "羽咋郡志賀町").await;
let city = result.unwrap();
assert_eq!(city.name, "羽咋郡志賀町");
let town = Town {
name: "末吉".to_string(),
koaza: "千古".to_string(),
lat: Some(37.006235),
lng: Some(136.779155),
};
assert!(city.towns.contains(&town));
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn 同期_石川県羽咋郡志賀町_成功() {
let city_master_api = CityMasterApi {
server_url: "https://geolonia.github.io/japanese-addresses/api/ja",
};
let result = city_master_api.get_blocking("石川県", "羽咋郡志賀町");
let city = result.unwrap();
assert_eq!(city.name, "羽咋郡志賀町");
let town = Town {
name: "末吉".to_string(),
koaza: "千古".to_string(),
lat: Some(37.006235),
lng: Some(136.779155),
};
assert!(city.towns.contains(&town));
}

#[tokio::test]
async fn 非同期_誤った市区町村名_失敗() {
let city_master_api = CityMasterApi {
server_url: "https://geolonia.github.io/japanese-addresses/api/ja",
};
let result = city_master_api.get("石川県", "敦賀市").await;
assert!(result.is_err());
assert_eq!(
result.err().unwrap().error_message,
format!(
"{}/石川県/敦賀市.jsonを取得できませんでした",
city_master_api.server_url
)
);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn 同期_誤った市区町村名_失敗() {
let city_master_api = CityMasterApi {
server_url: "https://geolonia.github.io/japanese-addresses/api/ja",
};
let result = city_master_api.get_blocking("石川県", "敦賀市");
assert!(result.is_err());
assert_eq!(
result.err().unwrap().error_message,
format!(
"{}/石川県/敦賀市.jsonを取得できませんでした",
city_master_api.server_url
)
);
}
}
Loading
Loading