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

feat: adjust enroll logic and output for the new subscription plans #8661

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl CliState {
#[cfg(test)]
mod test {
use super::*;
use crate::cloud::subscription::SubscriptionName;

#[tokio::test]
async fn test_cli_spaces() -> Result<()> {
Expand All @@ -93,7 +94,7 @@ mod test {
"name1",
vec!["[email protected]", "[email protected]"],
Some(&Subscription::new(
"name1".to_string(),
SubscriptionName::Gold,
false,
None,
None,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use super::SpacesRepository;
use crate::cloud::space::Space;
use crate::cloud::subscription::Subscription;
use crate::cloud::subscription::{Subscription, SubscriptionName};
use ockam_core::async_trait;
use ockam_core::Result;
use ockam_node::database::{Boolean, FromSqlxError, Nullable, SqlxDatabase, ToVoid};
use sqlx::any::AnyRow;
use sqlx::*;
use std::str::FromStr;
use time::OffsetDateTime;

#[derive(Clone)]
Expand All @@ -31,7 +32,7 @@ impl SpacesSqlxDatabase {
.fetch_optional(&*self.database.pool)
.await
.into_core()?;
Ok(row.map(|r| r.subscription()))
row.map(|r| r.subscription()).transpose()
}

async fn set_as_default(&self, space_id: &str, transaction: &mut AnyConnection) -> Result<()> {
Expand Down Expand Up @@ -113,11 +114,11 @@ impl SpacesRepository for SpacesSqlxDatabase {
DO UPDATE SET space_id = $1, name = $2, is_free_trial = $3, marketplace = $4, start_date = $5, end_date = $6",
)
.bind(&space.id)
.bind(&subscription.name)
.bind(subscription.name.to_string())
.bind(subscription.is_free_trial)
.bind(&subscription.marketplace)
.bind(start_date.map(|d| d.unix_timestamp()))
.bind(end_date.map(|d| d.unix_timestamp()));
.bind(start_date.map(|d| d.into_inner().unix_timestamp()))
.bind(end_date.map(|d| d.into_inner().unix_timestamp()));
query.execute(&mut *transaction).await.void()?;
}
// remove the subscription
Expand Down Expand Up @@ -300,24 +301,27 @@ pub(super) struct SubscriptionRow {
}

impl SubscriptionRow {
pub(crate) fn subscription(&self) -> Subscription {
Subscription::new(
self.name.clone(),
pub(crate) fn subscription(&self) -> Result<Subscription> {
Ok(Subscription::new(
SubscriptionName::from_str(&self.name)?,
self.is_free_trial.to_bool(),
self.marketplace.to_option(),
self.start_date
.to_option()
.and_then(|t| OffsetDateTime::from_unix_timestamp(t).ok()),
.and_then(|t| OffsetDateTime::from_unix_timestamp(t).ok())
.and_then(|t| t.try_into().ok()),
self.end_date
.to_option()
.and_then(|t| OffsetDateTime::from_unix_timestamp(t).ok()),
)
.and_then(|t| OffsetDateTime::from_unix_timestamp(t).ok())
.and_then(|t| t.try_into().ok()),
))
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::cloud::subscription::SubscriptionName;
use ockam_node::database::with_dbs;
use std::ops::Add;
use time::ext::NumericalDuration;
Expand All @@ -343,11 +347,11 @@ mod test {
"[email protected]".to_string(),
],
subscription: Some(Subscription::new(
"premium".to_string(),
SubscriptionName::Basic,
false,
Some("aws".to_string()),
Some(OffsetDateTime::now_utc()),
Some(OffsetDateTime::now_utc().add(2.days())),
Some(OffsetDateTime::now_utc().try_into().unwrap()),
Some(OffsetDateTime::now_utc().add(2.days()).try_into().unwrap()),
)),
};

Expand Down
121 changes: 84 additions & 37 deletions implementations/rust/ockam/ockam_api/src/cloud/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ use ockam_node::Context;
use crate::cloud::email_address::EmailAddress;
use crate::cloud::project::models::AdminInfo;
use crate::cloud::project::{Project, ProjectsOrchestratorApi};
use crate::cloud::subscription::Subscription;
use crate::cloud::subscription::{Subscription, SUBSCRIPTION_PAGE};
use crate::cloud::{ControllerClient, HasSecureClient};
use crate::colors::{color_primary, color_uri, color_warn};
use crate::fmt_log;
use crate::nodes::InMemoryNode;
use crate::output::{comma_separated, Output};
use crate::terminal::fmt;
use crate::{fmt_log, UtcDateTime};

const TARGET: &str = "ockam_api::cloud::space";

Expand All @@ -39,8 +39,11 @@ impl Space {
self.name.clone()
}

pub fn has_subscription(&self) -> bool {
self.subscription.is_some()
pub fn has_valid_subscription(&self) -> bool {
self.subscription
.as_ref()
.map(|s| s.is_valid())
.unwrap_or(false)
}

pub fn is_in_free_trial_subscription(&self) -> bool {
Expand All @@ -52,46 +55,40 @@ impl Space {
.unwrap_or_default()
}

pub fn subscription_status_message(&self, space_is_new: bool) -> crate::Result<String> {
pub fn subscription_status_message(&self) -> crate::Result<String> {
let mut f = String::new();
if let Some(subscription) = &self.subscription {
let trial_text = if subscription.is_free_trial {
"Trial of the "
} else {
""
};
writeln!(
f,
"{}",
fmt_log!(
"This Space has a {} Subscription attached to it.",
color_primary(&subscription.name)
"This Space has a {}{} Subscription attached to it.",
trial_text,
subscription.name.colored(),
)
)?;
if let (Some(start_date), Some(end_date)) =
(&subscription.start_date(), &subscription.end_date())
{
writeln!(
f,
"{}",
fmt_log!(
"Your trial started on {} and will end in {}.",
color_primary(start_date.format_human()?),
color_primary(end_date.diff_human(&UtcDateTime::now()))
)
)?;
}
if subscription.is_free_trial {
if space_is_new {
writeln!(f)?;
writeln!(f, "{}", fmt_log!("As a courtesy, we created a temporary Space for you, so you can continue to build.\n"))?;
writeln!(
f,
"{}",
fmt_log!(
"Please subscribe to an Ockam plan within two weeks {}",
color_uri("https://www.ockam.io/pricing")
)
)?;
writeln!(f, "{}", fmt_log!("{}", color_warn("If you don't subscribe in that time, your Space and all associated Projects will be permanently deleted.")))?;
} else if let (Some(start_date), Some(end_date)) =
(&subscription.start_date(), &subscription.end_date())
{
writeln!(f)?;
writeln!(
f,
"{}",
fmt_log!(
"Your free trial started on {} and will end on {}.\n",
start_date,
end_date
)
)?;
writeln!(f, "{}", fmt_log!("Please subscribe to an Ockam plan before the trial ends to avoid any service interruptions {}", color_uri("https://www.ockam.io/pricing")))?;
writeln!(f, "{}", fmt_log!("{}", color_warn("If you don't subscribe in that time, your Space and all associated Projects will be permanently deleted.")))?;
}
writeln!(f)?;
writeln!(f, "{}", fmt_log!("Please go to {} and subscribe before the trial ends to avoid any service interruptions.", color_uri(SUBSCRIPTION_PAGE)))?;
writeln!(f, "{}", fmt_log!("{}", color_warn("If you don't subscribe in that time, your Space and all associated Projects will be permanently deleted.")))?;
}
} else {
writeln!(
Expand Down Expand Up @@ -362,10 +359,10 @@ impl ControllerClient {

#[cfg(test)]
pub mod tests {
use quickcheck::{quickcheck, Arbitrary, Gen, TestResult};

use crate::cloud::space::CreateSpace;
use crate::schema::tests::validate_with_schema;
use quickcheck::{quickcheck, Arbitrary, Gen, TestResult};
use time::OffsetDateTime;

use super::*;

Expand Down Expand Up @@ -402,4 +399,54 @@ pub mod tests {
}
}
}

#[test]
fn valid_subscription_check() {
let mut g = Gen::new(100);
let mut space = Space::arbitrary(&mut g);

// No subscription
space.subscription = None;
assert!(!space.has_valid_subscription());

// Paid subscription
let mut sub = Subscription::arbitrary(&mut g);
sub.is_free_trial = false;
space.subscription = Some(sub.clone());
assert!(space.has_valid_subscription());

// Trial subscription with no dates
let mut sub = Subscription::arbitrary(&mut g);
sub.is_free_trial = true;
sub.start_date = None;
sub.end_date = None;
space.subscription = Some(sub.clone());
assert!(!space.has_valid_subscription());

// Trial subscription with date values
sub.start_date = Some(
(OffsetDateTime::now_utc() - time::Duration::days(1))
.try_into()
.unwrap(),
);
sub.end_date = None;
space.subscription = Some(sub.clone());
assert!(!space.has_valid_subscription());

sub.end_date = Some(
(OffsetDateTime::now_utc() - time::Duration::hours(1))
.try_into()
.unwrap(),
);
space.subscription = Some(sub.clone());
assert!(!space.has_valid_subscription());

sub.end_date = Some(
(OffsetDateTime::now_utc() + time::Duration::hours(1))
.try_into()
.unwrap(),
);
space.subscription = Some(sub.clone());
assert!(space.has_valid_subscription());
}
}
Loading
Loading