DEV: Update linting (#189)
This commit is contained in:
parent
a3883d2a9a
commit
d33cf2921e
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"globals": {
|
|
||||||
"Stripe": true
|
|
||||||
},
|
|
||||||
"extends": "eslint-config-discourse"
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require("@discourse/lint-configs/eslint");
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require("@discourse/lint-configs/prettier");
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require("@discourse/lint-configs/template-lint");
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
plugins: ["ember-template-lint-plugin-discourse"],
|
|
||||||
extends: "discourse:recommended",
|
|
||||||
};
|
|
52
Gemfile.lock
52
Gemfile.lock
|
@ -8,35 +8,45 @@ GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
json (2.6.2)
|
json (2.7.1)
|
||||||
parallel (1.22.1)
|
language_server-protocol (3.17.0.3)
|
||||||
parser (3.1.2.1)
|
parallel (1.24.0)
|
||||||
|
parser (3.3.0.4)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
prettier_print (1.2.0)
|
racc
|
||||||
|
prettier_print (1.2.1)
|
||||||
|
racc (1.7.3)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
regexp_parser (2.6.0)
|
regexp_parser (2.9.0)
|
||||||
rexml (3.2.5)
|
rexml (3.2.6)
|
||||||
rubocop (1.36.0)
|
rubocop (1.60.0)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
|
language_server-protocol (>= 3.17.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.1.2.1)
|
parser (>= 3.3.0.2)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
regexp_parser (>= 1.8, < 3.0)
|
regexp_parser (>= 1.8, < 3.0)
|
||||||
rexml (>= 3.2.5, < 4.0)
|
rexml (>= 3.2.5, < 4.0)
|
||||||
rubocop-ast (>= 1.20.1, < 2.0)
|
rubocop-ast (>= 1.30.0, < 2.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (>= 1.4.0, < 3.0)
|
unicode-display_width (>= 2.4.0, < 3.0)
|
||||||
rubocop-ast (1.21.0)
|
rubocop-ast (1.30.0)
|
||||||
parser (>= 3.1.1.0)
|
parser (>= 3.2.1.0)
|
||||||
rubocop-discourse (3.0)
|
rubocop-capybara (2.20.0)
|
||||||
rubocop (>= 1.1.0)
|
rubocop (~> 1.41)
|
||||||
rubocop-rspec (>= 2.0.0)
|
rubocop-discourse (3.6.0)
|
||||||
rubocop-rspec (2.13.2)
|
rubocop (>= 1.59.0)
|
||||||
rubocop (~> 1.33)
|
rubocop-rspec (>= 2.25.0)
|
||||||
ruby-progressbar (1.11.0)
|
rubocop-factory_bot (2.25.1)
|
||||||
syntax_tree (5.1.0)
|
rubocop (~> 1.41)
|
||||||
|
rubocop-rspec (2.26.1)
|
||||||
|
rubocop (~> 1.40)
|
||||||
|
rubocop-capybara (~> 2.17)
|
||||||
|
rubocop-factory_bot (~> 2.22)
|
||||||
|
ruby-progressbar (1.13.0)
|
||||||
|
syntax_tree (6.2.0)
|
||||||
prettier_print (>= 1.2.0)
|
prettier_print (>= 1.2.0)
|
||||||
unicode-display_width (2.3.0)
|
unicode-display_width (2.5.0)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
@ -47,4 +57,4 @@ DEPENDENCIES
|
||||||
translations-manager!
|
translations-manager!
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.3.4
|
2.5.4
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { action } from "@ember/object";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import { equal } from "@ember/object/computed";
|
|
||||||
import { setting } from "discourse/lib/computed";
|
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
import { action } from "@ember/object";
|
||||||
|
import { equal } from "@ember/object/computed";
|
||||||
import { later } from "@ember/runloop";
|
import { later } from "@ember/runloop";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import { setting } from "discourse/lib/computed";
|
||||||
|
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
const SIDEBAR_BODY_CLASS = "subscription-campaign-sidebar";
|
const SIDEBAR_BODY_CLASS = "subscription-campaign-sidebar";
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
document.body.classList.remove(SIDEBAR_BODY_CLASS);
|
document.body.classList.remove(SIDEBAR_BODY_CLASS);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { Input } from "@ember/component";
|
||||||
|
import { fn, hash } from "@ember/helper";
|
||||||
import DButton from "discourse/components/d-button";
|
import DButton from "discourse/components/d-button";
|
||||||
import DModal from "discourse/components/d-modal";
|
import DModal from "discourse/components/d-modal";
|
||||||
import Component from "@glimmer/component";
|
|
||||||
import { fn, hash } from "@ember/helper";
|
|
||||||
import i18n from "discourse-common/helpers/i18n";
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
import { Input } from "@ember/component";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
|
||||||
|
|
||||||
export default class AdminCancelSubscription extends Component {
|
export default class AdminCancelSubscription extends Component {
|
||||||
@tracked refund;
|
@tracked refund;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ["product-list"],
|
classNames: ["product-list"],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import ComboBoxComponent from "select-kit/components/combo-box";
|
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
import ComboBoxComponent from "select-kit/components/combo-box";
|
||||||
|
|
||||||
export default ComboBoxComponent.extend({
|
export default ComboBoxComponent.extend({
|
||||||
pluginApiIdentifiers: ["subscribe-ca-province-select"],
|
pluginApiIdentifiers: ["subscribe-ca-province-select"],
|
||||||
|
|
|
@ -24,5 +24,8 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
didDestroyElement() {},
|
|
||||||
|
didDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import ComboBoxComponent from "select-kit/components/combo-box";
|
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
import ComboBoxComponent from "select-kit/components/combo-box";
|
||||||
|
|
||||||
export default ComboBoxComponent.extend({
|
export default ComboBoxComponent.extend({
|
||||||
pluginApiIdentifiers: ["subscribe-country-select"],
|
pluginApiIdentifiers: ["subscribe-country-select"],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import ComboBoxComponent from "select-kit/components/combo-box";
|
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
import ComboBoxComponent from "select-kit/components/combo-box";
|
||||||
|
|
||||||
export default ComboBoxComponent.extend({
|
export default ComboBoxComponent.extend({
|
||||||
pluginApiIdentifiers: ["subscribe-us-state-select"],
|
pluginApiIdentifiers: ["subscribe-us-state-select"],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import AdminCoupon from "discourse/plugins/discourse-subscriptions/discourse/models/admin-coupon";
|
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
import AdminCoupon from "discourse/plugins/discourse-subscriptions/discourse/models/admin-coupon";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
creating: null,
|
creating: null,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
router: service(),
|
router: service(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import DiscourseURL from "discourse/lib/url";
|
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import { alias } from "@ember/object/computed";
|
import { alias } from "@ember/object/computed";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
import DiscourseURL from "discourse/lib/url";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
const RECURRING = "recurring";
|
const RECURRING = "recurring";
|
||||||
const ONE_TIME = "one_time";
|
const ONE_TIME = "one_time";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
router: service(),
|
router: service(),
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import AdminCancelSubscription from "../components/modal/admin-cancel-subscription";
|
|
||||||
import AdminSubscription from "../models/admin-subscription";
|
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import I18n from "discourse-i18n";
|
import I18n from "discourse-i18n";
|
||||||
|
import AdminCancelSubscription from "../components/modal/admin-cancel-subscription";
|
||||||
|
import AdminSubscription from "../models/admin-subscription";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
modal: service(),
|
modal: service(),
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { action } from "@ember/object";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import { action } from "@ember/object";
|
||||||
import I18n from "I18n";
|
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import User from "discourse/models/user";
|
import User from "discourse/models/user";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
@discourseComputed()
|
@discourseComputed()
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
/* global Stripe */
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
|
import { not } from "@ember/object/computed";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import I18n from "I18n";
|
||||||
import Subscription from "discourse/plugins/discourse-subscriptions/discourse/models/subscription";
|
import Subscription from "discourse/plugins/discourse-subscriptions/discourse/models/subscription";
|
||||||
import Transaction from "discourse/plugins/discourse-subscriptions/discourse/models/transaction";
|
import Transaction from "discourse/plugins/discourse-subscriptions/discourse/models/transaction";
|
||||||
import I18n from "I18n";
|
|
||||||
import { not } from "@ember/object/computed";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
|
/* global Stripe */
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
|
|
||||||
loading: false,
|
loading: false,
|
||||||
saved: false,
|
saved: false,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.set(
|
this.set(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
|
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
|
||||||
|
|
||||||
export default function formatUnixDate(timestamp) {
|
export default function formatUnixDate(timestamp) {
|
||||||
if (timestamp) {
|
if (timestamp) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ export default {
|
||||||
name: "setup-subscriptions",
|
name: "setup-subscriptions",
|
||||||
initialize(container) {
|
initialize(container) {
|
||||||
withPluginApi("0.8.11", (api) => {
|
withPluginApi("0.8.11", (api) => {
|
||||||
const siteSettings = container.lookup("site-settings:main");
|
const siteSettings = container.lookup("service:site-settings");
|
||||||
const isNavLinkEnabled =
|
const isNavLinkEnabled =
|
||||||
siteSettings.discourse_subscriptions_extra_nav_subscribe;
|
siteSettings.discourse_subscriptions_extra_nav_subscribe;
|
||||||
if (isNavLinkEnabled) {
|
if (isNavLinkEnabled) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
const AdminCoupon = EmberObject.extend({
|
const AdminCoupon = EmberObject.extend({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Plan from "discourse/plugins/discourse-subscriptions/discourse/models/plan";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import Plan from "discourse/plugins/discourse-subscriptions/discourse/models/plan";
|
||||||
|
|
||||||
const AdminPlan = Plan.extend({
|
const AdminPlan = Plan.extend({
|
||||||
isNew: false,
|
isNew: false,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
|
||||||
const AdminProduct = EmberObject.extend({
|
const AdminProduct = EmberObject.extend({
|
||||||
isNew: false,
|
isNew: false,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL from "discourse-common/lib/get-url";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
const AdminSubscription = EmberObject.extend({
|
const AdminSubscription = EmberObject.extend({
|
||||||
@discourseComputed("status")
|
@discourseComputed("status")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
const Subscription = EmberObject.extend({
|
const Subscription = EmberObject.extend({
|
||||||
@discourseComputed("status")
|
@discourseComputed("status")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
const UserPayment = EmberObject.extend({
|
const UserPayment = EmberObject.extend({
|
||||||
@discourseComputed("amount")
|
@discourseComputed("amount")
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import Plan from "discourse/plugins/discourse-subscriptions/discourse/models/plan";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
import Plan from "discourse/plugins/discourse-subscriptions/discourse/models/plan";
|
||||||
|
|
||||||
const UserSubscription = EmberObject.extend({
|
const UserSubscription = EmberObject.extend({
|
||||||
@discourseComputed("status")
|
@discourseComputed("status")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { action } from "@ember/object";
|
||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
import AdminCoupon from "discourse/plugins/discourse-subscriptions/discourse/models/admin-coupon";
|
import AdminCoupon from "discourse/plugins/discourse-subscriptions/discourse/models/admin-coupon";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
model() {
|
model() {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Route from "@ember/routing/route";
|
|
||||||
import AdminProduct from "discourse/plugins/discourse-subscriptions/discourse/models/admin-product";
|
|
||||||
import I18n from "I18n";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import AdminProduct from "discourse/plugins/discourse-subscriptions/discourse/models/admin-product";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
import AdminPlan from "discourse/plugins/discourse-subscriptions/discourse/models/admin-plan";
|
|
||||||
import Group from "discourse/models/group";
|
|
||||||
import { hash } from "rsvp";
|
import { hash } from "rsvp";
|
||||||
|
import Group from "discourse/models/group";
|
||||||
|
import AdminPlan from "discourse/plugins/discourse-subscriptions/discourse/models/admin-plan";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Route from "@ember/routing/route";
|
|
||||||
import AdminProduct from "discourse/plugins/discourse-subscriptions/discourse/models/admin-product";
|
|
||||||
import AdminPlan from "discourse/plugins/discourse-subscriptions/discourse/models/admin-plan";
|
|
||||||
import I18n from "I18n";
|
|
||||||
import { hash } from "rsvp";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { hash } from "rsvp";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import AdminPlan from "discourse/plugins/discourse-subscriptions/discourse/models/admin-plan";
|
||||||
|
import AdminProduct from "discourse/plugins/discourse-subscriptions/discourse/models/admin-product";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Route from "@ember/routing/route";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
import Product from "discourse/plugins/discourse-subscriptions/discourse/models/product";
|
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import Product from "discourse/plugins/discourse-subscriptions/discourse/models/product";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
router: service(),
|
router: service(),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
import Product from "discourse/plugins/discourse-subscriptions/discourse/models/product";
|
|
||||||
import Plan from "discourse/plugins/discourse-subscriptions/discourse/models/plan";
|
import Plan from "discourse/plugins/discourse-subscriptions/discourse/models/plan";
|
||||||
|
import Product from "discourse/plugins/discourse-subscriptions/discourse/models/product";
|
||||||
import Subscription from "discourse/plugins/discourse-subscriptions/discourse/models/subscription";
|
import Subscription from "discourse/plugins/discourse-subscriptions/discourse/models/subscription";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Route from "@ember/routing/route";
|
|
||||||
import UserSubscription from "discourse/plugins/discourse-subscriptions/discourse/models/user-subscription";
|
|
||||||
import I18n from "I18n";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import UserSubscription from "discourse/plugins/discourse-subscriptions/discourse/models/user-subscription";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
|
router: service(),
|
||||||
|
|
||||||
templateName: "user/billing",
|
templateName: "user/billing",
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
if (this.currentUser.id !== this.modelFor("user").id) {
|
if (this.currentUser.id !== this.modelFor("user").id) {
|
||||||
this.replaceWith("userActivity");
|
this.router.replaceWith("userActivity");
|
||||||
} else {
|
} else {
|
||||||
controller.setProperties({ model });
|
controller.setProperties({ model });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
<DSection
|
{{body-class "user-billing-page"}}
|
||||||
@pageClass="user-billing"
|
|
||||||
@class="user-secondary-navigation"
|
<section class="user-secondary-navigation">
|
||||||
@scrollTop="false"
|
|
||||||
>
|
|
||||||
<MobileNav
|
<MobileNav
|
||||||
@class="activity-nav"
|
|
||||||
@desktopClass="action-list nav-stacked"
|
@desktopClass="action-list nav-stacked"
|
||||||
@currentPath={{router._router.currentPath}}
|
@currentPath={{router._router.currentPath}}
|
||||||
|
class="activity-nav"
|
||||||
>
|
>
|
||||||
<li>
|
<li>
|
||||||
<LinkTo @route="user.billing.subscriptions">
|
<LinkTo @route="user.billing.subscriptions">
|
||||||
|
@ -20,7 +18,7 @@
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
</MobileNav>
|
</MobileNav>
|
||||||
</DSection>
|
</section>
|
||||||
|
|
||||||
<section class="user-content">
|
<section class="user-content">
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
|
|
|
@ -90,14 +90,14 @@ def import_subscriptions(procourse_import)
|
||||||
product_ids = DiscourseSubscriptions::Product.all.pluck(:external_id)
|
product_ids = DiscourseSubscriptions::Product.all.pluck(:external_id)
|
||||||
|
|
||||||
all_customers = get_stripe_customers
|
all_customers = get_stripe_customers
|
||||||
puts "Total available Stripe Customers: #{all_customers.length.to_s}, the first of which is customer id: #{all_customers[0][:description]}"
|
puts "Total available Stripe Customers: #{all_customers.length}, the first of which is customer id: #{all_customers[0][:description]}"
|
||||||
|
|
||||||
subscriptions = get_stripe_subscriptions
|
subscriptions = get_stripe_subscriptions
|
||||||
puts "Total Active Subscriptions available: #{subscriptions.length.to_s}"
|
puts "Total Active Subscriptions available: #{subscriptions.length}"
|
||||||
|
|
||||||
subscriptions_for_products =
|
subscriptions_for_products =
|
||||||
subscriptions.select { |sub| product_ids.include?(sub[:items][:data][0][:price][:product]) }
|
subscriptions.select { |sub| product_ids.include?(sub[:items][:data][0][:price][:product]) }
|
||||||
puts "Total Subscriptions matching Products to Import: #{subscriptions_for_products.length.to_s}"
|
puts "Total Subscriptions matching Products to Import: #{subscriptions_for_products.length}"
|
||||||
|
|
||||||
subscriptions_for_products.each do |subscription|
|
subscriptions_for_products.each do |subscription|
|
||||||
product_id = subscription[:items][:data][0][:plan][:product]
|
product_id = subscription[:items][:data][0][:plan][:product]
|
||||||
|
|
10
package.json
10
package.json
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "discourse-subscriptions",
|
"name": "discourse-subscriptions",
|
||||||
"version": "1.0.0",
|
"private": true,
|
||||||
"repository": "https://github.com/discourse/discourse-subscriptions",
|
|
||||||
"author": "Discourse",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint-config-discourse": "^3.4.0"
|
"@discourse/lint-configs": "^1.3.5",
|
||||||
|
"ember-template-lint": "^5.13.0",
|
||||||
|
"eslint": "^8.56.0",
|
||||||
|
"prettier": "^2.8.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# version: 2.8.1
|
# version: 2.8.1
|
||||||
# url: https://github.com/discourse/discourse-subscriptions
|
# url: https://github.com/discourse/discourse-subscriptions
|
||||||
# authors: Rimian Perkins, Justin DiRose
|
# authors: Rimian Perkins, Justin DiRose
|
||||||
# transpile_js: true
|
|
||||||
|
|
||||||
enabled_site_setting :discourse_subscriptions_enabled
|
enabled_site_setting :discourse_subscriptions_enabled
|
||||||
|
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::Customer do
|
||||||
RSpec.describe Customer do
|
let(:user) { Fabricate(:user) }
|
||||||
let(:user) { Fabricate(:user) }
|
let(:stripe_customer) { { id: "cus_id4567" } }
|
||||||
let(:stripe_customer) { { id: "cus_id4567" } }
|
|
||||||
|
|
||||||
it "has a table name" do
|
it "has a table name" do
|
||||||
expect(described_class.table_name).to eq "discourse_subscriptions_customers"
|
expect(described_class.table_name).to eq "discourse_subscriptions_customers"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates" do
|
it "creates" do
|
||||||
customer = described_class.create_customer(user, stripe_customer)
|
customer = described_class.create_customer(user, stripe_customer)
|
||||||
expect(customer.customer_id).to eq "cus_id4567"
|
expect(customer.customer_id).to eq "cus_id4567"
|
||||||
expect(customer.user_id).to eq user.id
|
expect(customer.user_id).to eq user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has a user scope" do
|
it "has a user scope" do
|
||||||
described_class.create_customer(user, stripe_customer)
|
described_class.create_customer(user, stripe_customer)
|
||||||
customer = described_class.find_user(user)
|
customer = described_class.find_user(user)
|
||||||
expect(customer.customer_id).to eq "cus_id4567"
|
expect(customer.customer_id).to eq "cus_id4567"
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,87 +2,83 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::Admin::CouponsController do
|
||||||
RSpec.describe Admin::CouponsController do
|
it "is a subclass of AdminController" do
|
||||||
it "is a subclass of AdminController" do
|
expect(DiscourseSubscriptions::Admin::CouponsController < ::Admin::AdminController).to eq(true)
|
||||||
expect(DiscourseSubscriptions::Admin::CouponsController < ::Admin::AdminController).to eq(
|
end
|
||||||
true,
|
|
||||||
)
|
context "when unauthenticated" do
|
||||||
end
|
it "does nothing" do
|
||||||
|
::Stripe::PromotionCode.expects(:list).never
|
||||||
|
get "/s/admin/coupons.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when authenticated" do
|
||||||
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
|
||||||
|
before { sign_in(admin) }
|
||||||
|
|
||||||
|
describe "#index" do
|
||||||
|
it "returns a list of promo codes" do
|
||||||
|
::Stripe::PromotionCode
|
||||||
|
.expects(:list)
|
||||||
|
.with({ limit: 100 })
|
||||||
|
.returns({ data: [{ id: "promo_123", coupon: { valid: true } }] })
|
||||||
|
|
||||||
context "when unauthenticated" do
|
|
||||||
it "does nothing" do
|
|
||||||
::Stripe::PromotionCode.expects(:list).never
|
|
||||||
get "/s/admin/coupons.json"
|
get "/s/admin/coupons.json"
|
||||||
expect(response.status).to eq(404)
|
expect(response.status).to eq(200)
|
||||||
|
expect(response.parsed_body[0]["id"]).to eq("promo_123")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "only returns valid promo codes" do
|
||||||
|
::Stripe::PromotionCode
|
||||||
|
.expects(:list)
|
||||||
|
.with({ limit: 100 })
|
||||||
|
.returns({ data: [{ id: "promo_123", coupon: { valid: false } }] })
|
||||||
|
|
||||||
|
get "/s/admin/coupons.json"
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(response.parsed_body).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when authenticated" do
|
describe "#create" do
|
||||||
let(:admin) { Fabricate(:admin) }
|
it "creates a coupon with an amount off" do
|
||||||
|
::Stripe::Coupon.expects(:create).returns(id: "coup_123")
|
||||||
|
::Stripe::PromotionCode.expects(:create).returns(
|
||||||
|
{ code: "p123", coupon: { amount_off: 2000 } },
|
||||||
|
)
|
||||||
|
|
||||||
before { sign_in(admin) }
|
post "/s/admin/coupons.json",
|
||||||
|
params: {
|
||||||
describe "#index" do
|
promo: "p123",
|
||||||
it "returns a list of promo codes" do
|
discount_type: "amount",
|
||||||
::Stripe::PromotionCode
|
discount: "2000",
|
||||||
.expects(:list)
|
active: true,
|
||||||
.with({ limit: 100 })
|
}
|
||||||
.returns({ data: [{ id: "promo_123", coupon: { valid: true } }] })
|
expect(response.status).to eq(200)
|
||||||
|
expect(response.parsed_body["code"]).to eq("p123")
|
||||||
get "/s/admin/coupons.json"
|
expect(response.parsed_body["coupon"]["amount_off"]).to eq(2000)
|
||||||
expect(response.status).to eq(200)
|
|
||||||
expect(response.parsed_body[0]["id"]).to eq("promo_123")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "only returns valid promo codes" do
|
|
||||||
::Stripe::PromotionCode
|
|
||||||
.expects(:list)
|
|
||||||
.with({ limit: 100 })
|
|
||||||
.returns({ data: [{ id: "promo_123", coupon: { valid: false } }] })
|
|
||||||
|
|
||||||
get "/s/admin/coupons.json"
|
|
||||||
expect(response.status).to eq(200)
|
|
||||||
expect(response.parsed_body).to be_blank
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#create" do
|
it "creates a coupon with a percent off" do
|
||||||
it "creates a coupon with an amount off" do
|
::Stripe::Coupon.expects(:create).returns(id: "coup_123")
|
||||||
::Stripe::Coupon.expects(:create).returns(id: "coup_123")
|
::Stripe::PromotionCode.expects(:create).returns(
|
||||||
::Stripe::PromotionCode.expects(:create).returns(
|
{ code: "p123", coupon: { percent_off: 20 } },
|
||||||
{ code: "p123", coupon: { amount_off: 2000 } },
|
)
|
||||||
)
|
|
||||||
|
|
||||||
post "/s/admin/coupons.json",
|
post "/s/admin/coupons.json",
|
||||||
params: {
|
params: {
|
||||||
promo: "p123",
|
promo: "p123",
|
||||||
discount_type: "amount",
|
discount_type: "percent",
|
||||||
discount: "2000",
|
discount: "20",
|
||||||
active: true,
|
active: true,
|
||||||
}
|
}
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(response.parsed_body["code"]).to eq("p123")
|
expect(response.parsed_body["code"]).to eq("p123")
|
||||||
expect(response.parsed_body["coupon"]["amount_off"]).to eq(2000)
|
expect(response.parsed_body["coupon"]["percent_off"]).to eq(20)
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a coupon with a percent off" do
|
|
||||||
::Stripe::Coupon.expects(:create).returns(id: "coup_123")
|
|
||||||
::Stripe::PromotionCode.expects(:create).returns(
|
|
||||||
{ code: "p123", coupon: { percent_off: 20 } },
|
|
||||||
)
|
|
||||||
|
|
||||||
post "/s/admin/coupons.json",
|
|
||||||
params: {
|
|
||||||
promo: "p123",
|
|
||||||
discount_type: "percent",
|
|
||||||
discount: "20",
|
|
||||||
active: true,
|
|
||||||
}
|
|
||||||
expect(response.status).to eq(200)
|
|
||||||
expect(response.parsed_body["code"]).to eq("p123")
|
|
||||||
expect(response.parsed_body["coupon"]["percent_off"]).to eq(20)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,172 +2,166 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::Admin::PlansController do
|
||||||
module Admin
|
it "is a subclass of AdminController" do
|
||||||
RSpec.describe PlansController do
|
expect(DiscourseSubscriptions::Admin::PlansController < ::Admin::AdminController).to eq(true)
|
||||||
it "is a subclass of AdminController" do
|
end
|
||||||
expect(DiscourseSubscriptions::Admin::PlansController < ::Admin::AdminController).to eq(
|
|
||||||
true,
|
context "when not authenticated" do
|
||||||
)
|
describe "index" do
|
||||||
|
it "does not get the plans" do
|
||||||
|
::Stripe::Price.expects(:list).never
|
||||||
|
get "/s/admin/plans.json"
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when not authenticated" do
|
it "not ok" do
|
||||||
describe "index" do
|
get "/s/admin/plans.json"
|
||||||
it "does not get the plans" do
|
expect(response.status).to eq 404
|
||||||
::Stripe::Price.expects(:list).never
|
end
|
||||||
get "/s/admin/plans.json"
|
end
|
||||||
end
|
|
||||||
|
|
||||||
it "not ok" do
|
describe "create" do
|
||||||
get "/s/admin/plans.json"
|
it "does not create a plan" do
|
||||||
expect(response.status).to eq 404
|
::Stripe::Price.expects(:create).never
|
||||||
end
|
post "/s/admin/plans.json", params: { name: "Rick Astley", amount: 1, interval: "week" }
|
||||||
end
|
|
||||||
|
|
||||||
describe "create" do
|
|
||||||
it "does not create a plan" do
|
|
||||||
::Stripe::Price.expects(:create).never
|
|
||||||
post "/s/admin/plans.json", params: { name: "Rick Astley", amount: 1, interval: "week" }
|
|
||||||
end
|
|
||||||
|
|
||||||
it "is not ok" do
|
|
||||||
post "/s/admin/plans.json", params: { name: "Rick Astley", amount: 1, interval: "week" }
|
|
||||||
expect(response.status).to eq 404
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "show" do
|
|
||||||
it "does not show the plan" do
|
|
||||||
::Stripe::Price.expects(:retrieve).never
|
|
||||||
get "/s/admin/plans/plan_12345.json"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "is not ok" do
|
|
||||||
get "/s/admin/plans/plan_12345.json"
|
|
||||||
expect(response.status).to eq 404
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "update" do
|
|
||||||
it "does not update a plan" do
|
|
||||||
::Stripe::Price.expects(:update).never
|
|
||||||
delete "/s/admin/plans/plan_12345.json"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when authenticated" do
|
it "is not ok" do
|
||||||
let(:admin) { Fabricate(:admin) }
|
post "/s/admin/plans.json", params: { name: "Rick Astley", amount: 1, interval: "week" }
|
||||||
|
expect(response.status).to eq 404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
before { sign_in(admin) }
|
describe "show" do
|
||||||
|
it "does not show the plan" do
|
||||||
|
::Stripe::Price.expects(:retrieve).never
|
||||||
|
get "/s/admin/plans/plan_12345.json"
|
||||||
|
end
|
||||||
|
|
||||||
describe "index" do
|
it "is not ok" do
|
||||||
it "lists the plans" do
|
get "/s/admin/plans/plan_12345.json"
|
||||||
::Stripe::Price.expects(:list).with(nil)
|
expect(response.status).to eq 404
|
||||||
get "/s/admin/plans.json"
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "lists the plans for the product" do
|
describe "update" do
|
||||||
::Stripe::Price.expects(:list).with({ product: "prod_id123" })
|
it "does not update a plan" do
|
||||||
get "/s/admin/plans.json", params: { product_id: "prod_id123" }
|
::Stripe::Price.expects(:update).never
|
||||||
end
|
delete "/s/admin/plans/plan_12345.json"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "show" do
|
context "when authenticated" do
|
||||||
it "shows a plan" do
|
let(:admin) { Fabricate(:admin) }
|
||||||
::Stripe::Price.expects(:retrieve).with("plan_12345").returns(currency: "aud")
|
|
||||||
get "/s/admin/plans/plan_12345.json"
|
|
||||||
expect(response.status).to eq 200
|
|
||||||
end
|
|
||||||
|
|
||||||
it "upcases the currency" do
|
before { sign_in(admin) }
|
||||||
::Stripe::Price
|
|
||||||
.expects(:retrieve)
|
|
||||||
.with("plan_12345")
|
|
||||||
.returns(currency: "aud", recurring: { interval: "year" })
|
|
||||||
get "/s/admin/plans/plan_12345.json"
|
|
||||||
|
|
||||||
plan = response.parsed_body
|
describe "index" do
|
||||||
expect(plan["currency"]).to eq "AUD"
|
it "lists the plans" do
|
||||||
expect(plan["interval"]).to eq "year"
|
::Stripe::Price.expects(:list).with(nil)
|
||||||
end
|
get "/s/admin/plans.json"
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "create" do
|
it "lists the plans for the product" do
|
||||||
it "creates a plan with a nickname" do
|
::Stripe::Price.expects(:list).with({ product: "prod_id123" })
|
||||||
::Stripe::Price.expects(:create).with(has_entry(:nickname, "Veg"))
|
get "/s/admin/plans.json", params: { product_id: "prod_id123" }
|
||||||
post "/s/admin/plans.json", params: { nickname: "Veg", metadata: { group_name: "" } }
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a plan with a currency" do
|
describe "show" do
|
||||||
::Stripe::Price.expects(:create).with(has_entry(:currency, "AUD"))
|
it "shows a plan" do
|
||||||
post "/s/admin/plans.json", params: { currency: "AUD", metadata: { group_name: "" } }
|
::Stripe::Price.expects(:retrieve).with("plan_12345").returns(currency: "aud")
|
||||||
end
|
get "/s/admin/plans/plan_12345.json"
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
end
|
||||||
|
|
||||||
it "creates a plan with an interval" do
|
it "upcases the currency" do
|
||||||
::Stripe::Price.expects(:create).with(has_entry(recurring: { interval: "week" }))
|
::Stripe::Price
|
||||||
post "/s/admin/plans.json",
|
.expects(:retrieve)
|
||||||
params: {
|
.with("plan_12345")
|
||||||
type: "recurring",
|
.returns(currency: "aud", recurring: { interval: "year" })
|
||||||
interval: "week",
|
get "/s/admin/plans/plan_12345.json"
|
||||||
metadata: {
|
|
||||||
group_name: "",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a plan as a one-time purchase" do
|
plan = response.parsed_body
|
||||||
::Stripe::Price.expects(:create).with(Not(has_key(:recurring)))
|
expect(plan["currency"]).to eq "AUD"
|
||||||
post "/s/admin/plans.json", params: { metadata: { group_name: "" } }
|
expect(plan["interval"]).to eq "year"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "creates a plan with an amount" do
|
describe "create" do
|
||||||
::Stripe::Price.expects(:create).with(has_entry(:unit_amount, "102"))
|
it "creates a plan with a nickname" do
|
||||||
post "/s/admin/plans.json", params: { amount: "102", metadata: { group_name: "" } }
|
::Stripe::Price.expects(:create).with(has_entry(:nickname, "Veg"))
|
||||||
end
|
post "/s/admin/plans.json", params: { nickname: "Veg", metadata: { group_name: "" } }
|
||||||
|
end
|
||||||
|
|
||||||
it "creates a plan with a product" do
|
it "creates a plan with a currency" do
|
||||||
::Stripe::Price.expects(:create).with(has_entry(product: "prod_walterwhite"))
|
::Stripe::Price.expects(:create).with(has_entry(:currency, "AUD"))
|
||||||
post "/s/admin/plans.json",
|
post "/s/admin/plans.json", params: { currency: "AUD", metadata: { group_name: "" } }
|
||||||
params: {
|
end
|
||||||
product: "prod_walterwhite",
|
|
||||||
metadata: {
|
|
||||||
group_name: "",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a plan with an active status" do
|
it "creates a plan with an interval" do
|
||||||
::Stripe::Price.expects(:create).with(has_entry(:active, "false"))
|
::Stripe::Price.expects(:create).with(has_entry(recurring: { interval: "week" }))
|
||||||
post "/s/admin/plans.json", params: { active: "false", metadata: { group_name: "" } }
|
post "/s/admin/plans.json",
|
||||||
end
|
params: {
|
||||||
|
type: "recurring",
|
||||||
|
interval: "week",
|
||||||
|
metadata: {
|
||||||
|
group_name: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: Need to fix the metadata tests
|
it "creates a plan as a one-time purchase" do
|
||||||
# I think mocha has issues with the metadata fields here.
|
::Stripe::Price.expects(:create).with(Not(has_key(:recurring)))
|
||||||
|
post "/s/admin/plans.json", params: { metadata: { group_name: "" } }
|
||||||
|
end
|
||||||
|
|
||||||
#it 'has metadata' do
|
it "creates a plan with an amount" do
|
||||||
# ::Stripe::Price.expects(:create).with(has_entry(:group_name, "discourse-user-group-name"))
|
::Stripe::Price.expects(:create).with(has_entry(:unit_amount, "102"))
|
||||||
# post "/s/admin/plans.json", params: { amount: "100", metadata: { group_name: 'discourse-user-group-name' } }
|
post "/s/admin/plans.json", params: { amount: "102", metadata: { group_name: "" } }
|
||||||
#end
|
end
|
||||||
|
|
||||||
#it "creates a plan with a trial period" do
|
it "creates a plan with a product" do
|
||||||
# ::Stripe::Price.expects(:create).with(has_entry(trial_period_days: '14'))
|
::Stripe::Price.expects(:create).with(has_entry(product: "prod_walterwhite"))
|
||||||
# post "/s/admin/plans.json", params: { trial_period_days: '14' }
|
post "/s/admin/plans.json",
|
||||||
#end
|
params: {
|
||||||
end
|
product: "prod_walterwhite",
|
||||||
|
metadata: {
|
||||||
|
group_name: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
describe "update" do
|
it "creates a plan with an active status" do
|
||||||
it "updates a plan" do
|
::Stripe::Price.expects(:create).with(has_entry(:active, "false"))
|
||||||
::Stripe::Price.expects(:update)
|
post "/s/admin/plans.json", params: { active: "false", metadata: { group_name: "" } }
|
||||||
patch "/s/admin/plans/plan_12345.json",
|
end
|
||||||
params: {
|
|
||||||
trial_period_days: "14",
|
# TODO: Need to fix the metadata tests
|
||||||
metadata: {
|
# I think mocha has issues with the metadata fields here.
|
||||||
group_name: "discourse-user-group-name",
|
|
||||||
},
|
#it 'has metadata' do
|
||||||
}
|
# ::Stripe::Price.expects(:create).with(has_entry(:group_name, "discourse-user-group-name"))
|
||||||
end
|
# post "/s/admin/plans.json", params: { amount: "100", metadata: { group_name: 'discourse-user-group-name' } }
|
||||||
end
|
#end
|
||||||
|
|
||||||
|
#it "creates a plan with a trial period" do
|
||||||
|
# ::Stripe::Price.expects(:create).with(has_entry(trial_period_days: '14'))
|
||||||
|
# post "/s/admin/plans.json", params: { trial_period_days: '14' }
|
||||||
|
#end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "update" do
|
||||||
|
it "updates a plan" do
|
||||||
|
::Stripe::Price.expects(:update)
|
||||||
|
patch "/s/admin/plans/plan_12345.json",
|
||||||
|
params: {
|
||||||
|
trial_period_days: "14",
|
||||||
|
metadata: {
|
||||||
|
group_name: "discourse-user-group-name",
|
||||||
|
},
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,132 +2,126 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::Admin::ProductsController do
|
||||||
module Admin
|
it "is a subclass of AdminController" do
|
||||||
RSpec.describe ProductsController do
|
expect(DiscourseSubscriptions::Admin::ProductsController < ::Admin::AdminController).to eq(true)
|
||||||
it "is a subclass of AdminController" do
|
end
|
||||||
expect(DiscourseSubscriptions::Admin::ProductsController < ::Admin::AdminController).to eq(
|
|
||||||
true,
|
context "when unauthenticated" do
|
||||||
|
it "does not list the products" do
|
||||||
|
::Stripe::Product.expects(:list).never
|
||||||
|
get "/s/admin/products.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not create the product" do
|
||||||
|
::Stripe::Product.expects(:create).never
|
||||||
|
post "/s/admin/products.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not show the product" do
|
||||||
|
::Stripe::Product.expects(:retrieve).never
|
||||||
|
get "/s/admin/products/prod_qwerty123.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not update the product" do
|
||||||
|
::Stripe::Product.expects(:update).never
|
||||||
|
put "/s/admin/products/prod_qwerty123.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not delete the product" do
|
||||||
|
::Stripe::Product.expects(:delete).never
|
||||||
|
delete "/s/admin/products/u2.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when authenticated" do
|
||||||
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
|
||||||
|
before { sign_in(admin) }
|
||||||
|
|
||||||
|
describe "index" do
|
||||||
|
it "gets the empty products" do
|
||||||
|
SiteSetting.discourse_subscriptions_public_key = "public-key"
|
||||||
|
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
||||||
|
get "/s/admin/products.json"
|
||||||
|
expect(response.parsed_body).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "create" do
|
||||||
|
it "is of product type service" do
|
||||||
|
::Stripe::Product.expects(:create).with(has_entry(:type, "service"))
|
||||||
|
post "/s/admin/products.json", params: {}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has a name" do
|
||||||
|
::Stripe::Product.expects(:create).with(has_entry(:name, "Jesse Pinkman"))
|
||||||
|
post "/s/admin/products.json", params: { name: "Jesse Pinkman" }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has an active attribute" do
|
||||||
|
::Stripe::Product.expects(:create).with(has_entry(active: "false"))
|
||||||
|
post "/s/admin/products.json", params: { active: "false" }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has a statement descriptor" do
|
||||||
|
::Stripe::Product.expects(:create).with(
|
||||||
|
has_entry(statement_descriptor: "Blessed are the cheesemakers"),
|
||||||
)
|
)
|
||||||
|
post "/s/admin/products.json",
|
||||||
|
params: {
|
||||||
|
statement_descriptor: "Blessed are the cheesemakers",
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when unauthenticated" do
|
it "has no statement descriptor if empty" do
|
||||||
it "does not list the products" do
|
::Stripe::Product.expects(:create).with(has_key(:statement_descriptor)).never
|
||||||
::Stripe::Product.expects(:list).never
|
post "/s/admin/products.json", params: { statement_descriptor: "" }
|
||||||
get "/s/admin/products.json"
|
|
||||||
expect(response.status).to eq(404)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not create the product" do
|
|
||||||
::Stripe::Product.expects(:create).never
|
|
||||||
post "/s/admin/products.json"
|
|
||||||
expect(response.status).to eq(404)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not show the product" do
|
|
||||||
::Stripe::Product.expects(:retrieve).never
|
|
||||||
get "/s/admin/products/prod_qwerty123.json"
|
|
||||||
expect(response.status).to eq(404)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not update the product" do
|
|
||||||
::Stripe::Product.expects(:update).never
|
|
||||||
put "/s/admin/products/prod_qwerty123.json"
|
|
||||||
expect(response.status).to eq(404)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not delete the product" do
|
|
||||||
::Stripe::Product.expects(:delete).never
|
|
||||||
delete "/s/admin/products/u2.json"
|
|
||||||
expect(response.status).to eq(404)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when authenticated" do
|
it "has metadata" do
|
||||||
let(:admin) { Fabricate(:admin) }
|
::Stripe::Product.expects(:create).with(
|
||||||
|
has_entry(
|
||||||
|
metadata: {
|
||||||
|
description: "Oi, I think he just said bless be all the bignoses!",
|
||||||
|
repurchaseable: "false",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
before { sign_in(admin) }
|
post "/s/admin/products.json",
|
||||||
|
params: {
|
||||||
|
metadata: {
|
||||||
|
description: "Oi, I think he just said bless be all the bignoses!",
|
||||||
|
repurchaseable: "false",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "index" do
|
describe "show" do
|
||||||
it "gets the empty products" do
|
it "retrieves the product" do
|
||||||
SiteSetting.discourse_subscriptions_public_key = "public-key"
|
::Stripe::Product.expects(:retrieve).with("prod_walterwhite")
|
||||||
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
get "/s/admin/products/prod_walterwhite.json"
|
||||||
get "/s/admin/products.json"
|
end
|
||||||
expect(response.parsed_body).to be_empty
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "create" do
|
describe "update" do
|
||||||
it "is of product type service" do
|
it "updates the product" do
|
||||||
::Stripe::Product.expects(:create).with(has_entry(:type, "service"))
|
::Stripe::Product.expects(:update)
|
||||||
post "/s/admin/products.json", params: {}
|
patch "/s/admin/products/prod_walterwhite.json", params: {}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "has a name" do
|
describe "delete" do
|
||||||
::Stripe::Product.expects(:create).with(has_entry(:name, "Jesse Pinkman"))
|
it "deletes the product" do
|
||||||
post "/s/admin/products.json", params: { name: "Jesse Pinkman" }
|
::Stripe::Product.expects(:delete).with("prod_walterwhite")
|
||||||
end
|
delete "/s/admin/products/prod_walterwhite.json"
|
||||||
|
|
||||||
it "has an active attribute" do
|
|
||||||
::Stripe::Product.expects(:create).with(has_entry(active: "false"))
|
|
||||||
post "/s/admin/products.json", params: { active: "false" }
|
|
||||||
end
|
|
||||||
|
|
||||||
it "has a statement descriptor" do
|
|
||||||
::Stripe::Product.expects(:create).with(
|
|
||||||
has_entry(statement_descriptor: "Blessed are the cheesemakers"),
|
|
||||||
)
|
|
||||||
post "/s/admin/products.json",
|
|
||||||
params: {
|
|
||||||
statement_descriptor: "Blessed are the cheesemakers",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "has no statement descriptor if empty" do
|
|
||||||
::Stripe::Product.expects(:create).with(has_key(:statement_descriptor)).never
|
|
||||||
post "/s/admin/products.json", params: { statement_descriptor: "" }
|
|
||||||
end
|
|
||||||
|
|
||||||
it "has metadata" do
|
|
||||||
::Stripe::Product.expects(:create).with(
|
|
||||||
has_entry(
|
|
||||||
metadata: {
|
|
||||||
description: "Oi, I think he just said bless be all the bignoses!",
|
|
||||||
repurchaseable: "false",
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
post "/s/admin/products.json",
|
|
||||||
params: {
|
|
||||||
metadata: {
|
|
||||||
description: "Oi, I think he just said bless be all the bignoses!",
|
|
||||||
repurchaseable: "false",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "show" do
|
|
||||||
it "retrieves the product" do
|
|
||||||
::Stripe::Product.expects(:retrieve).with("prod_walterwhite")
|
|
||||||
get "/s/admin/products/prod_walterwhite.json"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "update" do
|
|
||||||
it "updates the product" do
|
|
||||||
::Stripe::Product.expects(:update)
|
|
||||||
patch "/s/admin/products/prod_walterwhite.json", params: {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "delete" do
|
|
||||||
it "deletes the product" do
|
|
||||||
::Stripe::Product.expects(:delete).with("prod_walterwhite")
|
|
||||||
delete "/s/admin/products/prod_walterwhite.json"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,141 +2,139 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::Admin::SubscriptionsController do
|
||||||
RSpec.describe Admin::SubscriptionsController do
|
it "is a subclass of AdminController" do
|
||||||
it "is a subclass of AdminController" do
|
expect(DiscourseSubscriptions::Admin::SubscriptionsController < ::Admin::AdminController).to eq(
|
||||||
expect(
|
true,
|
||||||
DiscourseSubscriptions::Admin::SubscriptionsController < ::Admin::AdminController,
|
)
|
||||||
).to eq(true)
|
end
|
||||||
|
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:customer) do
|
||||||
|
Fabricate(:customer, user_id: user.id, customer_id: "c_123", product_id: "pr_34578")
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
Fabricate(:subscription, external_id: "sub_12345", customer_id: customer.id)
|
||||||
|
Fabricate(:subscription, external_id: "sub_77777", customer_id: customer.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when unauthenticated" do
|
||||||
|
it "does nothing" do
|
||||||
|
::Stripe::Subscription.expects(:list).never
|
||||||
|
get "/s/admin/subscriptions.json"
|
||||||
|
expect(response.status).to eq(404)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:user) { Fabricate(:user) }
|
it "does not destroy a subscription" do
|
||||||
let(:customer) do
|
::Stripe::Subscription.expects(:delete).never
|
||||||
Fabricate(:customer, user_id: user.id, customer_id: "c_123", product_id: "pr_34578")
|
patch "/s/admin/subscriptions/sub_12345.json"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
context "when authenticated" do
|
||||||
Fabricate(:subscription, external_id: "sub_12345", customer_id: customer.id)
|
let(:admin) { Fabricate(:admin) }
|
||||||
Fabricate(:subscription, external_id: "sub_77777", customer_id: customer.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when unauthenticated" do
|
before { sign_in(admin) }
|
||||||
it "does nothing" do
|
|
||||||
::Stripe::Subscription.expects(:list).never
|
describe "index" do
|
||||||
|
before do
|
||||||
|
SiteSetting.discourse_subscriptions_public_key = "public-key"
|
||||||
|
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "gets the subscriptions and products" do
|
||||||
|
::Stripe::Subscription
|
||||||
|
.expects(:list)
|
||||||
|
.with(expand: ["data.plan.product"], limit: 10, starting_after: nil)
|
||||||
|
.returns(has_more: false, data: [{ id: "sub_12345" }, { id: "sub_nope" }])
|
||||||
get "/s/admin/subscriptions.json"
|
get "/s/admin/subscriptions.json"
|
||||||
expect(response.status).to eq(404)
|
subscriptions = response.parsed_body["data"][0]["id"]
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(subscriptions).to eq("sub_12345")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not destroy a subscription" do
|
it "handles starting at a different point in the set" do
|
||||||
::Stripe::Subscription.expects(:delete).never
|
::Stripe::Subscription
|
||||||
patch "/s/admin/subscriptions/sub_12345.json"
|
.expects(:list)
|
||||||
|
.with(expand: ["data.plan.product"], limit: 10, starting_after: "sub_nope")
|
||||||
|
.returns(has_more: false, data: [{ id: "sub_77777" }, { id: "sub_yepnoep" }])
|
||||||
|
get "/s/admin/subscriptions.json", params: { last_record: "sub_nope" }
|
||||||
|
subscriptions = response.parsed_body["data"][0]["id"]
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(subscriptions).to eq("sub_77777")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when authenticated" do
|
describe "destroy" do
|
||||||
let(:admin) { Fabricate(:admin) }
|
let(:group) { Fabricate(:group, name: "subscribers") }
|
||||||
|
|
||||||
before { sign_in(admin) }
|
before { group.add(user) }
|
||||||
|
|
||||||
describe "index" do
|
it "deletes a customer" do
|
||||||
before do
|
::Stripe::Subscription
|
||||||
SiteSetting.discourse_subscriptions_public_key = "public-key"
|
.expects(:delete)
|
||||||
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
.with("sub_12345")
|
||||||
end
|
.returns(plan: { product: "pr_34578" }, customer: "c_123")
|
||||||
|
|
||||||
it "gets the subscriptions and products" do
|
expect { delete "/s/admin/subscriptions/sub_12345.json" }.to change {
|
||||||
::Stripe::Subscription
|
DiscourseSubscriptions::Customer.count
|
||||||
.expects(:list)
|
}.by(-1)
|
||||||
.with(expand: ["data.plan.product"], limit: 10, starting_after: nil)
|
|
||||||
.returns(has_more: false, data: [{ id: "sub_12345" }, { id: "sub_nope" }])
|
|
||||||
get "/s/admin/subscriptions.json"
|
|
||||||
subscriptions = response.parsed_body["data"][0]["id"]
|
|
||||||
|
|
||||||
expect(response.status).to eq(200)
|
|
||||||
expect(subscriptions).to eq("sub_12345")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "handles starting at a different point in the set" do
|
|
||||||
::Stripe::Subscription
|
|
||||||
.expects(:list)
|
|
||||||
.with(expand: ["data.plan.product"], limit: 10, starting_after: "sub_nope")
|
|
||||||
.returns(has_more: false, data: [{ id: "sub_77777" }, { id: "sub_yepnoep" }])
|
|
||||||
get "/s/admin/subscriptions.json", params: { last_record: "sub_nope" }
|
|
||||||
subscriptions = response.parsed_body["data"][0]["id"]
|
|
||||||
|
|
||||||
expect(response.status).to eq(200)
|
|
||||||
expect(subscriptions).to eq("sub_77777")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "destroy" do
|
it "removes the user from the group" do
|
||||||
let(:group) { Fabricate(:group, name: "subscribers") }
|
::Stripe::Subscription
|
||||||
|
.expects(:delete)
|
||||||
before { group.add(user) }
|
.with("sub_12345")
|
||||||
|
.returns(
|
||||||
it "deletes a customer" do
|
plan: {
|
||||||
::Stripe::Subscription
|
product: "pr_34578",
|
||||||
.expects(:delete)
|
metadata: {
|
||||||
.with("sub_12345")
|
group_name: "subscribers",
|
||||||
.returns(plan: { product: "pr_34578" }, customer: "c_123")
|
|
||||||
|
|
||||||
expect { delete "/s/admin/subscriptions/sub_12345.json" }.to change {
|
|
||||||
DiscourseSubscriptions::Customer.count
|
|
||||||
}.by(-1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "removes the user from the group" do
|
|
||||||
::Stripe::Subscription
|
|
||||||
.expects(:delete)
|
|
||||||
.with("sub_12345")
|
|
||||||
.returns(
|
|
||||||
plan: {
|
|
||||||
product: "pr_34578",
|
|
||||||
metadata: {
|
|
||||||
group_name: "subscribers",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
customer: "c_123",
|
},
|
||||||
)
|
customer: "c_123",
|
||||||
|
)
|
||||||
|
|
||||||
expect { delete "/s/admin/subscriptions/sub_12345.json" }.to change {
|
expect { delete "/s/admin/subscriptions/sub_12345.json" }.to change {
|
||||||
user.groups.count
|
user.groups.count
|
||||||
}.by(-1)
|
}.by(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not remove the user from the group" do
|
it "does not remove the user from the group" do
|
||||||
::Stripe::Subscription
|
::Stripe::Subscription
|
||||||
.expects(:delete)
|
.expects(:delete)
|
||||||
.with("sub_12345")
|
.with("sub_12345")
|
||||||
.returns(
|
.returns(
|
||||||
plan: {
|
plan: {
|
||||||
product: "pr_34578",
|
product: "pr_34578",
|
||||||
metadata: {
|
metadata: {
|
||||||
group_name: "group_does_not_exist",
|
group_name: "group_does_not_exist",
|
||||||
},
|
|
||||||
},
|
},
|
||||||
customer: "c_123",
|
},
|
||||||
)
|
customer: "c_123",
|
||||||
|
)
|
||||||
|
|
||||||
expect { delete "/s/admin/subscriptions/sub_12345.json" }.not_to change {
|
expect { delete "/s/admin/subscriptions/sub_12345.json" }.not_to change {
|
||||||
user.groups.count
|
user.groups.count
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "refunds if params[:refund] present" do
|
it "refunds if params[:refund] present" do
|
||||||
::Stripe::Subscription
|
::Stripe::Subscription
|
||||||
.expects(:delete)
|
.expects(:delete)
|
||||||
.with("sub_12345")
|
.with("sub_12345")
|
||||||
.returns(plan: { product: "pr_34578" }, customer: "c_123")
|
.returns(plan: { product: "pr_34578" }, customer: "c_123")
|
||||||
::Stripe::Subscription
|
::Stripe::Subscription
|
||||||
.expects(:retrieve)
|
.expects(:retrieve)
|
||||||
.with("sub_12345")
|
.with("sub_12345")
|
||||||
.returns(latest_invoice: "in_123")
|
.returns(latest_invoice: "in_123")
|
||||||
::Stripe::Invoice.expects(:retrieve).with("in_123").returns(payment_intent: "pi_123")
|
::Stripe::Invoice.expects(:retrieve).with("in_123").returns(payment_intent: "pi_123")
|
||||||
::Stripe::Refund.expects(:create).with({ payment_intent: "pi_123" })
|
::Stripe::Refund.expects(:create).with({ payment_intent: "pi_123" })
|
||||||
|
|
||||||
delete "/s/admin/subscriptions/sub_12345.json", params: { refund: true }
|
delete "/s/admin/subscriptions/sub_12345.json", params: { refund: true }
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,19 +2,17 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::AdminController do
|
||||||
RSpec.describe AdminController do
|
let(:admin) { Fabricate(:admin) }
|
||||||
let(:admin) { Fabricate(:admin) }
|
|
||||||
|
|
||||||
before { sign_in(admin) }
|
before { sign_in(admin) }
|
||||||
|
|
||||||
it "is a subclass of AdminController" do
|
it "is a subclass of AdminController" do
|
||||||
expect(DiscourseSubscriptions::AdminController < ::Admin::AdminController).to eq(true)
|
expect(DiscourseSubscriptions::AdminController < ::Admin::AdminController).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is ok" do
|
it "is ok" do
|
||||||
get "/s/admin.json"
|
get "/s/admin.json"
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,109 +2,105 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::HooksController do
|
||||||
RSpec.describe HooksController do
|
before { SiteSetting.discourse_subscriptions_webhook_secret = "zascharoo" }
|
||||||
before { SiteSetting.discourse_subscriptions_webhook_secret = "zascharoo" }
|
|
||||||
|
|
||||||
it "contructs a webhook event" do
|
it "constructs a webhook event" do
|
||||||
payload = "we-want-a-shrubbery"
|
payload = "we-want-a-shrubbery"
|
||||||
headers = { HTTP_STRIPE_SIGNATURE: "stripe-webhook-signature" }
|
headers = { HTTP_STRIPE_SIGNATURE: "stripe-webhook-signature" }
|
||||||
|
|
||||||
::Stripe::Webhook
|
::Stripe::Webhook
|
||||||
.expects(:construct_event)
|
.expects(:construct_event)
|
||||||
.with("we-want-a-shrubbery", "stripe-webhook-signature", "zascharoo")
|
.with("we-want-a-shrubbery", "stripe-webhook-signature", "zascharoo")
|
||||||
.returns(type: "something")
|
.returns(type: "something")
|
||||||
|
|
||||||
post "/s/hooks.json", params: payload, headers: headers
|
post "/s/hooks.json", params: payload, headers: headers
|
||||||
|
|
||||||
expect(response.status).to eq 200
|
expect(response.status).to eq 200
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "event types" do
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:customer) do
|
||||||
|
Fabricate(:customer, customer_id: "c_575768", product_id: "p_8654", user_id: user.id)
|
||||||
end
|
end
|
||||||
|
let(:group) { Fabricate(:group, name: "subscribers-group") }
|
||||||
|
|
||||||
describe "event types" do
|
let(:event_data) do
|
||||||
let(:user) { Fabricate(:user) }
|
{
|
||||||
let(:customer) do
|
object: {
|
||||||
Fabricate(:customer, customer_id: "c_575768", product_id: "p_8654", user_id: user.id)
|
customer: customer.customer_id,
|
||||||
end
|
plan: {
|
||||||
let(:group) { Fabricate(:group, name: "subscribers-group") }
|
product: customer.product_id,
|
||||||
|
metadata: {
|
||||||
let(:event_data) do
|
group_name: group.name,
|
||||||
{
|
|
||||||
object: {
|
|
||||||
customer: customer.customer_id,
|
|
||||||
plan: {
|
|
||||||
product: customer.product_id,
|
|
||||||
metadata: {
|
|
||||||
group_name: group.name,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "customer.subscription.updated" do
|
||||||
|
before do
|
||||||
|
event = { type: "customer.subscription.updated", data: event_data }
|
||||||
|
|
||||||
|
::Stripe::Webhook.stubs(:construct_event).returns(event)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "customer.subscription.updated" do
|
it "is successfull" do
|
||||||
before do
|
post "/s/hooks.json"
|
||||||
event = { type: "customer.subscription.updated", data: event_data }
|
expect(response.status).to eq 200
|
||||||
|
|
||||||
::Stripe::Webhook.stubs(:construct_event).returns(event)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "is successfull" do
|
|
||||||
post "/s/hooks.json"
|
|
||||||
expect(response.status).to eq 200
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "completing the subscription" do
|
|
||||||
it "does not add the user to the group" do
|
|
||||||
event_data[:object][:status] = "incomplete"
|
|
||||||
event_data[:previous_attributes] = { status: "incomplete" }
|
|
||||||
|
|
||||||
expect { post "/s/hooks.json" }.not_to change { user.groups.count }
|
|
||||||
|
|
||||||
expect(response.status).to eq 200
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not add the user to the group" do
|
|
||||||
event_data[:object][:status] = "incomplete"
|
|
||||||
event_data[:previous_attributes] = { status: "something-else" }
|
|
||||||
|
|
||||||
expect { post "/s/hooks.json" }.not_to change { user.groups.count }
|
|
||||||
|
|
||||||
expect(response.status).to eq 200
|
|
||||||
end
|
|
||||||
|
|
||||||
it "adds the user to the group when completing the transaction" do
|
|
||||||
event_data[:object][:status] = "complete"
|
|
||||||
event_data[:previous_attributes] = { status: "incomplete" }
|
|
||||||
|
|
||||||
expect { post "/s/hooks.json" }.to change { user.groups.count }.by(1)
|
|
||||||
|
|
||||||
expect(response.status).to eq 200
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "customer.subscription.deleted" do
|
describe "completing the subscription" do
|
||||||
before do
|
it "does not add the user to the group" do
|
||||||
event = { type: "customer.subscription.deleted", data: event_data }
|
event_data[:object][:status] = "incomplete"
|
||||||
|
event_data[:previous_attributes] = { status: "incomplete" }
|
||||||
|
|
||||||
::Stripe::Webhook.stubs(:construct_event).returns(event)
|
expect { post "/s/hooks.json" }.not_to change { user.groups.count }
|
||||||
|
|
||||||
group.add(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "deletes the customer" do
|
|
||||||
expect { post "/s/hooks.json" }.to change { DiscourseSubscriptions::Customer.count }.by(
|
|
||||||
-1,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(response.status).to eq 200
|
expect(response.status).to eq 200
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes the user from the group" do
|
it "does not add the user to the group" do
|
||||||
expect { post "/s/hooks.json" }.to change { user.groups.count }.by(-1)
|
event_data[:object][:status] = "incomplete"
|
||||||
|
event_data[:previous_attributes] = { status: "something-else" }
|
||||||
|
|
||||||
|
expect { post "/s/hooks.json" }.not_to change { user.groups.count }
|
||||||
|
|
||||||
expect(response.status).to eq 200
|
expect(response.status).to eq 200
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "adds the user to the group when completing the transaction" do
|
||||||
|
event_data[:object][:status] = "complete"
|
||||||
|
event_data[:previous_attributes] = { status: "incomplete" }
|
||||||
|
|
||||||
|
expect { post "/s/hooks.json" }.to change { user.groups.count }.by(1)
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "customer.subscription.deleted" do
|
||||||
|
before do
|
||||||
|
event = { type: "customer.subscription.deleted", data: event_data }
|
||||||
|
|
||||||
|
::Stripe::Webhook.stubs(:construct_event).returns(event)
|
||||||
|
|
||||||
|
group.add(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "deletes the customer" do
|
||||||
|
expect { post "/s/hooks.json" }.to change { DiscourseSubscriptions::Customer.count }.by(-1)
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
end
|
||||||
|
|
||||||
|
it "removes the user from the group" do
|
||||||
|
expect { post "/s/hooks.json" }.to change { user.groups.count }.by(-1)
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,63 +2,61 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::User::PaymentsController do
|
||||||
RSpec.describe User::PaymentsController do
|
it "is a subclass of ApplicationController" do
|
||||||
it "is a subclass of ApplicationController" do
|
expect(DiscourseSubscriptions::User::PaymentsController < ::ApplicationController).to eq(true)
|
||||||
expect(DiscourseSubscriptions::User::PaymentsController < ::ApplicationController).to eq(true)
|
end
|
||||||
|
|
||||||
|
context "when not authenticated" do
|
||||||
|
it "does not get the payment intents" do
|
||||||
|
::Stripe::PaymentIntent.expects(:list).never
|
||||||
|
get "/s/user/payments.json"
|
||||||
|
expect(response.status).to eq(403)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when authenticated" do
|
||||||
|
let(:user) { Fabricate(:user, email: "zasch@example.com") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
Fabricate(:customer, customer_id: "c_345678", user_id: user.id)
|
||||||
|
Fabricate(:product, external_id: "prod_8675309")
|
||||||
|
Fabricate(:product, external_id: "prod_8675310")
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when not authenticated" do
|
it "gets payment intents" do
|
||||||
it "does not get the payment intents" do
|
created_time = Time.now
|
||||||
::Stripe::PaymentIntent.expects(:list).never
|
::Stripe::Invoice
|
||||||
get "/s/user/payments.json"
|
.expects(:list)
|
||||||
expect(response.status).to eq(403)
|
.with(customer: "c_345678")
|
||||||
end
|
.returns(
|
||||||
end
|
data: [
|
||||||
|
{ id: "inv_900007", lines: { data: [plan: { product: "prod_8675309" }] } },
|
||||||
|
{ id: "inv_900008", lines: { data: [plan: { product: "prod_8675310" }] } },
|
||||||
|
{ id: "inv_900008", lines: { data: [plan: { product: "prod_8675310" }] } },
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
context "when authenticated" do
|
::Stripe::PaymentIntent
|
||||||
let(:user) { Fabricate(:user, email: "zasch@example.com") }
|
.expects(:list)
|
||||||
|
.with(customer: "c_345678")
|
||||||
|
.returns(
|
||||||
|
data: [
|
||||||
|
{ id: "pi_900008", invoice: "inv_900008", created: created_time },
|
||||||
|
{ id: "pi_900008", invoice: "inv_900008", created: created_time },
|
||||||
|
{ id: "pi_900007", invoice: "inv_900007", created: Time.now },
|
||||||
|
{ id: "pi_007", invoice: "inv_007", created: Time.now },
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
before do
|
get "/s/user/payments.json"
|
||||||
sign_in(user)
|
|
||||||
Fabricate(:customer, customer_id: "c_345678", user_id: user.id)
|
|
||||||
Fabricate(:product, external_id: "prod_8675309")
|
|
||||||
Fabricate(:product, external_id: "prod_8675310")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "gets payment intents" do
|
parsed_body = response.parsed_body
|
||||||
created_time = Time.now
|
invoice = parsed_body[0]["invoice"]
|
||||||
::Stripe::Invoice
|
|
||||||
.expects(:list)
|
|
||||||
.with(customer: "c_345678")
|
|
||||||
.returns(
|
|
||||||
data: [
|
|
||||||
{ id: "inv_900007", lines: { data: [plan: { product: "prod_8675309" }] } },
|
|
||||||
{ id: "inv_900008", lines: { data: [plan: { product: "prod_8675310" }] } },
|
|
||||||
{ id: "inv_900008", lines: { data: [plan: { product: "prod_8675310" }] } },
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
::Stripe::PaymentIntent
|
expect(invoice).to eq("inv_900007")
|
||||||
.expects(:list)
|
expect(parsed_body.count).to eq(2)
|
||||||
.with(customer: "c_345678")
|
|
||||||
.returns(
|
|
||||||
data: [
|
|
||||||
{ id: "pi_900008", invoice: "inv_900008", created: created_time },
|
|
||||||
{ id: "pi_900008", invoice: "inv_900008", created: created_time },
|
|
||||||
{ id: "pi_900007", invoice: "inv_900007", created: Time.now },
|
|
||||||
{ id: "pi_007", invoice: "inv_007", created: Time.now },
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
get "/s/user/payments.json"
|
|
||||||
|
|
||||||
parsed_body = response.parsed_body
|
|
||||||
invoice = parsed_body[0]["invoice"]
|
|
||||||
|
|
||||||
expect(invoice).to eq("inv_900007")
|
|
||||||
expect(parsed_body.count).to eq(2)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,105 +2,103 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
module DiscourseSubscriptions
|
RSpec.describe DiscourseSubscriptions::User::SubscriptionsController do
|
||||||
RSpec.describe User::SubscriptionsController do
|
it "is a subclass of ApplicationController" do
|
||||||
it "is a subclass of ApplicationController" do
|
expect(DiscourseSubscriptions::User::SubscriptionsController < ::ApplicationController).to eq(
|
||||||
expect(DiscourseSubscriptions::User::SubscriptionsController < ::ApplicationController).to eq(
|
true,
|
||||||
true,
|
)
|
||||||
)
|
end
|
||||||
|
|
||||||
|
context "when not authenticated" do
|
||||||
|
it "does not get the subscriptions" do
|
||||||
|
::Stripe::Customer.expects(:list).never
|
||||||
|
get "/s/user/subscriptions.json"
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when not authenticated" do
|
it "does not destroy a subscription" do
|
||||||
it "does not get the subscriptions" do
|
::Stripe::Subscription.expects(:delete).never
|
||||||
::Stripe::Customer.expects(:list).never
|
patch "/s/user/subscriptions/sub_12345.json"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't update payment method for subscription" do
|
||||||
|
::Stripe::Subscription.expects(:update).never
|
||||||
|
::Stripe::PaymentMethod.expects(:attach).never
|
||||||
|
put "/s/user/subscriptions/sub_12345.json", params: { payment_method: "pm_abc123abc" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when authenticated" do
|
||||||
|
let(:user) { Fabricate(:user, email: "beanie@example.com") }
|
||||||
|
let(:customer) do
|
||||||
|
Fabricate(:customer, user_id: user.id, customer_id: "cus_23456", product_id: "prod_123")
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
Fabricate(:subscription, customer_id: customer.id, external_id: "sub_1234")
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "index" do
|
||||||
|
let(:plans) do
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
{ id: "plan_1", product: { name: "ACME Subscriptions" } },
|
||||||
|
{ id: "plan_2", product: { name: "ACME Other Subscriptions" } },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:customers) do
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: "cus_23456",
|
||||||
|
subscriptions: {
|
||||||
|
data: [
|
||||||
|
{ id: "sub_1234", items: { data: [price: { id: "plan_1" }] } },
|
||||||
|
{ id: "sub_4567", items: { data: [price: { id: "plan_2" }] } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "gets subscriptions" do
|
||||||
|
::Stripe::Price.expects(:list).with(expand: ["data.product"], limit: 100).returns(plans)
|
||||||
|
|
||||||
|
::Stripe::Customer
|
||||||
|
.expects(:list)
|
||||||
|
.with(email: user.email, expand: ["data.subscriptions"])
|
||||||
|
.returns(customers)
|
||||||
|
|
||||||
get "/s/user/subscriptions.json"
|
get "/s/user/subscriptions.json"
|
||||||
end
|
|
||||||
|
|
||||||
it "does not destroy a subscription" do
|
subscription = response.parsed_body.first
|
||||||
::Stripe::Subscription.expects(:delete).never
|
|
||||||
patch "/s/user/subscriptions/sub_12345.json"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "doesn't update payment method for subscription" do
|
expect(subscription).to eq(
|
||||||
::Stripe::Subscription.expects(:update).never
|
"id" => "sub_1234",
|
||||||
::Stripe::PaymentMethod.expects(:attach).never
|
"items" => {
|
||||||
put "/s/user/subscriptions/sub_12345.json", params: { payment_method: "pm_abc123abc" }
|
"data" => [{ "price" => { "id" => "plan_1" } }],
|
||||||
end
|
},
|
||||||
end
|
"plan" => {
|
||||||
|
"id" => "plan_1",
|
||||||
context "when authenticated" do
|
|
||||||
let(:user) { Fabricate(:user, email: "beanie@example.com") }
|
|
||||||
let(:customer) do
|
|
||||||
Fabricate(:customer, user_id: user.id, customer_id: "cus_23456", product_id: "prod_123")
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
|
||||||
sign_in(user)
|
|
||||||
Fabricate(:subscription, customer_id: customer.id, external_id: "sub_1234")
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "index" do
|
|
||||||
let(:plans) do
|
|
||||||
{
|
|
||||||
data: [
|
|
||||||
{ id: "plan_1", product: { name: "ACME Subscriptions" } },
|
|
||||||
{ id: "plan_2", product: { name: "ACME Other Subscriptions" } },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:customers) do
|
|
||||||
{
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
id: "cus_23456",
|
|
||||||
subscriptions: {
|
|
||||||
data: [
|
|
||||||
{ id: "sub_1234", items: { data: [price: { id: "plan_1" }] } },
|
|
||||||
{ id: "sub_4567", items: { data: [price: { id: "plan_2" }] } },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "gets subscriptions" do
|
|
||||||
::Stripe::Price.expects(:list).with(expand: ["data.product"], limit: 100).returns(plans)
|
|
||||||
|
|
||||||
::Stripe::Customer
|
|
||||||
.expects(:list)
|
|
||||||
.with(email: user.email, expand: ["data.subscriptions"])
|
|
||||||
.returns(customers)
|
|
||||||
|
|
||||||
get "/s/user/subscriptions.json"
|
|
||||||
|
|
||||||
subscription = response.parsed_body.first
|
|
||||||
|
|
||||||
expect(subscription).to eq(
|
|
||||||
"id" => "sub_1234",
|
|
||||||
"items" => {
|
|
||||||
"data" => [{ "price" => { "id" => "plan_1" } }],
|
|
||||||
},
|
|
||||||
"plan" => {
|
|
||||||
"id" => "plan_1",
|
|
||||||
"product" => {
|
|
||||||
"name" => "ACME Subscriptions",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"product" => {
|
"product" => {
|
||||||
"name" => "ACME Subscriptions",
|
"name" => "ACME Subscriptions",
|
||||||
},
|
},
|
||||||
)
|
},
|
||||||
end
|
"product" => {
|
||||||
|
"name" => "ACME Subscriptions",
|
||||||
|
},
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "update" do
|
describe "update" do
|
||||||
it "updates the payment method for subscription" do
|
it "updates the payment method for subscription" do
|
||||||
::Stripe::Subscription.expects(:update).once
|
::Stripe::Subscription.expects(:update).once
|
||||||
::Stripe::PaymentMethod.expects(:attach).once
|
::Stripe::PaymentMethod.expects(:attach).once
|
||||||
put "/s/user/subscriptions/sub_1234.json", params: { payment_method: "pm_abc123abc" }
|
put "/s/user/subscriptions/sub_1234.json", params: { payment_method: "pm_abc123abc" }
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ describe SiteSerializer do
|
||||||
SiteSetting.discourse_subscriptions_enabled = true
|
SiteSetting.discourse_subscriptions_enabled = true
|
||||||
SiteSetting.discourse_subscriptions_campaign_enabled = true
|
SiteSetting.discourse_subscriptions_campaign_enabled = true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is false if the goal_met date is < 7 days old" do
|
it "is false if the goal_met date is < 7 days old" do
|
||||||
Discourse.redis.set("subscriptions_goal_met_date", 10.days.ago)
|
Discourse.redis.set("subscriptions_goal_met_date", 10.days.ago)
|
||||||
data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
||||||
|
|
|
@ -4,12 +4,8 @@ require "rails_helper"
|
||||||
|
|
||||||
describe DiscourseSubscriptions::Campaign do
|
describe DiscourseSubscriptions::Campaign do
|
||||||
describe "campaign data is refreshed" do
|
describe "campaign data is refreshed" do
|
||||||
let (:user) {
|
let(:user) { Fabricate(:user) }
|
||||||
Fabricate(:user)
|
let(:user2) { Fabricate(:user) }
|
||||||
}
|
|
||||||
let (:user2) {
|
|
||||||
Fabricate(:user)
|
|
||||||
}
|
|
||||||
let(:subscription) do
|
let(:subscription) do
|
||||||
{
|
{
|
||||||
id: "sub_1234",
|
id: "sub_1234",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { acceptance, count } from "discourse/tests/helpers/qunit-helpers";
|
|
||||||
import { stubStripe } from "discourse/plugins/discourse-subscriptions/helpers/stripe";
|
|
||||||
import { visit } from "@ember/test-helpers";
|
import { visit } from "@ember/test-helpers";
|
||||||
import { test } from "qunit";
|
import { test } from "qunit";
|
||||||
|
import { acceptance, count } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import { stubStripe } from "discourse/plugins/discourse-subscriptions/helpers/stripe";
|
||||||
|
|
||||||
acceptance("Discourse Subscriptions", function (needs) {
|
acceptance("Discourse Subscriptions", function (needs) {
|
||||||
needs.user();
|
needs.user();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { acceptance, count } from "discourse/tests/helpers/qunit-helpers";
|
|
||||||
import { stubStripe } from "discourse/plugins/discourse-subscriptions/helpers/stripe";
|
|
||||||
import { click, visit } from "@ember/test-helpers";
|
import { click, visit } from "@ember/test-helpers";
|
||||||
import { test } from "qunit";
|
import { test } from "qunit";
|
||||||
import pretender, { response } from "discourse/tests/helpers/create-pretender";
|
import pretender, { response } from "discourse/tests/helpers/create-pretender";
|
||||||
|
import { acceptance, count } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import { stubStripe } from "discourse/plugins/discourse-subscriptions/helpers/stripe";
|
||||||
|
|
||||||
function singleProductPretender() {
|
function singleProductPretender() {
|
||||||
pretender.get("/s", () => {
|
pretender.get("/s", () => {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { count, discourseModule } from "discourse/tests/helpers/qunit-helpers";
|
import hbs from "htmlbars-inline-precompile";
|
||||||
import componentTest, {
|
import componentTest, {
|
||||||
setupRenderingTest,
|
setupRenderingTest,
|
||||||
} from "discourse/tests/helpers/component-test";
|
} from "discourse/tests/helpers/component-test";
|
||||||
import hbs from "htmlbars-inline-precompile";
|
import { count, discourseModule } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
|
||||||
discourseModule("payment-options", function (hooks) {
|
discourseModule("payment-options", function (hooks) {
|
||||||
setupRenderingTest(hooks);
|
setupRenderingTest(hooks);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
import hbs from "htmlbars-inline-precompile";
|
||||||
|
import componentTest, {
|
||||||
|
setupRenderingTest,
|
||||||
|
} from "discourse/tests/helpers/component-test";
|
||||||
import {
|
import {
|
||||||
count,
|
count,
|
||||||
discourseModule,
|
discourseModule,
|
||||||
query,
|
query,
|
||||||
} from "discourse/tests/helpers/qunit-helpers";
|
} from "discourse/tests/helpers/qunit-helpers";
|
||||||
import componentTest, {
|
|
||||||
setupRenderingTest,
|
|
||||||
} from "discourse/tests/helpers/component-test";
|
|
||||||
import hbs from "htmlbars-inline-precompile";
|
|
||||||
|
|
||||||
discourseModule("payment-plan", function (hooks) {
|
discourseModule("payment-plan", function (hooks) {
|
||||||
setupRenderingTest(hooks);
|
setupRenderingTest(hooks);
|
||||||
|
|
Loading…
Reference in New Issue