Skip to content

Commit

Permalink
add is_first_party to admin aggregator form
Browse files Browse the repository at this point in the history
  • Loading branch information
jbr committed Jul 7, 2023
1 parent 2cda6b1 commit 3c702d8
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 3 deletions.
1 change: 1 addition & 0 deletions app/src/ApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export interface NewAggregator {
api_url: string;
dap_url: string;
bearer_token: string;
is_first_party?: boolean;
}

export interface ApiToken {
Expand Down
20 changes: 19 additions & 1 deletion app/src/aggregators/AggregatorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ async function submit(

export function AggregatorForm({
handleSubmit,
showIsFirstParty = false,
}: {
handleSubmit: (
aggregator: NewAggregator,
helpers: FormikHelpers<NewAggregator>
) => void;
showIsFirstParty?: boolean;
}) {
const actionData = useActionData();
let errors: undefined | FormikErrors<NewAggregator> = undefined;
Expand All @@ -72,6 +74,7 @@ export function AggregatorForm({
api_url: "",
dap_url: "",
bearer_token: "",
is_first_party: showIsFirstParty ? true : undefined,
} as NewAggregator
}
onSubmit={handleSubmit}
Expand All @@ -88,6 +91,7 @@ export function AggregatorForm({
<ApiUrl {...props} />
<DapUrl {...props} />
<BearerToken {...props} />
{showIsFirstParty ? <IsFirstParty {...props} /> : null}
<Button
variant="primary"
type="submit"
Expand Down Expand Up @@ -135,6 +139,20 @@ export default function AggregatorFormPage() {
);
}

function IsFirstParty(props: FormikProps<NewAggregator>) {
return (
<FormGroup>
<Form.Switch
id="is_first_party"
label="First Party?"
onChange={props.handleChange}
onBlur={props.handleBlur}
checked={props.values.is_first_party}
/>
</FormGroup>
);
}

function Name(props: FormikProps<NewAggregator>) {
return (
<FormGroup>
Expand All @@ -148,7 +166,7 @@ function Name(props: FormikProps<NewAggregator>) {
onBlur={props.handleBlur}
value={props.values.name}
isInvalid={!!props.errors.name}
data-1p-ignore={true}
data-1p-ignore
/>
<FormControl.Feedback type="invalid">
{props.errors.name}
Expand Down
2 changes: 1 addition & 1 deletion app/src/shared-aggregators/SharedAggregatorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function SharedAggreatorForm() {
return (
<>
<h1>New Shared Aggregator</h1>
<AggregatorForm handleSubmit={handleSubmit} />
<AggregatorForm handleSubmit={handleSubmit} showIsFirstParty />
</>
);
}
4 changes: 3 additions & 1 deletion src/entity/aggregator/new_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct NewAggregator {
pub dap_url: Option<String>,
#[validate(required, custom = "base64", length(min = 8))]
pub bearer_token: Option<String>,
pub is_first_party: Option<bool>,
}

fn validate_role(role: &str) -> Result<(), ValidationError> {
Expand All @@ -49,6 +50,7 @@ fn https(url: &str) -> Result<(), ValidationError> {
impl NewAggregator {
pub fn build(self, account: Option<&Account>) -> Result<ActiveModel, Error> {
self.validate()?;

// unwrap safety: the below unwraps will never panic, because
// the above call to `NewAggregator::validate` will
// early-return if any of the required `Option`s is `None`.
Expand All @@ -72,7 +74,7 @@ impl NewAggregator {
created_at: OffsetDateTime::now_utc(),
updated_at: OffsetDateTime::now_utc(),
deleted_at: None,
is_first_party: account.is_none(),
is_first_party: account.is_none() && self.is_first_party.unwrap_or(true),
}
.into_active_model())
}
Expand Down
60 changes: 60 additions & 0 deletions tests/aggregators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,26 @@ mod create {
Ok(())
}

#[test(harness = set_up)]
async fn is_first_party_is_ignored(app: DivviupApi) -> TestResult {
let (user, account, ..) = fixtures::member(&app).await;

let mut new_aggregator = fixtures::new_aggregator();
new_aggregator.is_first_party = Some(true);
let mut conn = post(format!("/api/accounts/{}/aggregators", account.id))
.with_api_headers()
.with_state(user)
.with_request_json(new_aggregator)
.run_async(&app)
.await;
assert_response!(conn, 201);
let aggregator: Aggregator = conn.response_json().await;
assert!(!aggregator.is_first_party);
assert!(!aggregator.reload(app.db()).await?.unwrap().is_first_party);

Ok(())
}

#[test(harness = set_up)]
async fn invalid(app: DivviupApi) -> TestResult {
let (user, account, ..) = fixtures::member(&app).await;
Expand Down Expand Up @@ -835,6 +855,8 @@ mod shared_create {
);
assert_eq!(aggregator.role.as_ref(), new_aggregator.role.unwrap());
assert!(aggregator.account_id.is_none());

// defaults to true when not specified
assert!(aggregator.is_first_party);

let aggregator_from_db = Aggregators::find_by_id(aggregator.id)
Expand All @@ -848,6 +870,44 @@ mod shared_create {
Ok(())
}

#[test(harness = set_up)]
async fn is_first_party_true_is_accepted(app: DivviupApi) -> TestResult {
let (admin, ..) = fixtures::admin(&app).await;
let mut new_aggregator = fixtures::new_aggregator();
new_aggregator.is_first_party = Some(true);
let mut conn = post("/api/aggregators")
.with_api_headers()
.with_state(admin)
.with_request_json(new_aggregator)
.run_async(&app)
.await;
assert_response!(conn, 201);
let aggregator: Aggregator = conn.response_json().await;
assert!(aggregator.is_first_party);
assert!(aggregator.reload(app.db()).await?.unwrap().is_first_party);

Ok(())
}

#[test(harness = set_up)]
async fn is_first_party_false_is_accepted(app: DivviupApi) -> TestResult {
let (admin, ..) = fixtures::admin(&app).await;
let mut new_aggregator = fixtures::new_aggregator();
new_aggregator.is_first_party = Some(false);
let mut conn = post("/api/aggregators")
.with_api_headers()
.with_state(admin)
.with_request_json(new_aggregator)
.run_async(&app)
.await;
assert_response!(conn, 201);
let aggregator: Aggregator = conn.response_json().await;
assert!(!aggregator.is_first_party);
assert!(!aggregator.reload(app.db()).await?.unwrap().is_first_party);

Ok(())
}

#[test(harness = set_up)]
async fn as_nonadmin(app: DivviupApi) -> TestResult {
let (admin, ..) = fixtures::member(&app).await;
Expand Down
1 change: 1 addition & 0 deletions tests/harness/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub fn new_aggregator() -> NewAggregator {
api_url: Some(format!("https://api.{}.divviup.org/prefix/", random_name())),
dap_url: Some(format!("https://dap.{}.divviup.org", random_name())),
bearer_token: Some(random_name()),
is_first_party: None,
}
}

Expand Down

0 comments on commit 3c702d8

Please sign in to comment.