Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit79ca233

Browse files
authored
Merge pull requestfiliphric#22 from filiphric/add-pricing-page
Add pricing page
2 parents968a44e +b4e2b18 commit79ca233

File tree

24 files changed

+342
-39
lines changed

24 files changed

+342
-39
lines changed

‎.env_example‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ VUE_APP_GOOGLE_CLIENT_SECRET=""
44
# enable or disable google SSO for the trello application
55
VUE_APP_GOOGLE_ENABLED=""
66
# token generated by google oauth playground, this is a token of a user you want to log in to the app
7-
GOOGLE_REFRESH_TOKEN=""
7+
GOOGLE_REFRESH_TOKEN=""
8+
# token for geolocation support, that you can get from https://api.ipgeolocation.io
9+
VUE_APP_GEOLOCATION_API_KEY=""

‎backend/api/location-routes.ts‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
importaxiosfrom'axios'
2+
constjsonServer=require('json-server');
3+
constapp=jsonServer.create();
4+
5+
consteuCountries=['BE','EL','LT','PT','BG','ES','LU','RO','CZ','FR','HU','SI','DK','HR','MT','SK','DE','IT','NL','FI','EE','CY','AT','SE','IE','LV','PL']
6+
7+
constdiscountCountries=[{
8+
countryCode:'SK',
9+
discount:20
10+
}]
11+
12+
app.get('/',(req,res,next)=>{
13+
14+
axios
15+
.get(`https://api.ipgeolocation.io/ipgeo?apiKey=${process.env.VUE_APP_GEOLOCATION_API_KEY}&fields=country_code2`)
16+
.then(({ data})=>{
17+
18+
19+
constlocale=data.country_code2
20+
constcountryDiscount=discountCountries.find(c=>c.countryCode===locale)
21+
constresult={
22+
location:locale.toLowerCase(),
23+
currency:euCountries.includes(locale) ?'EUR' :locale==='UK' ?'GBP' :'USD',
24+
discountEligible:countryDiscount ?true :false,
25+
discountAmount:countryDiscount?.discount
26+
}
27+
28+
constresponse=res.status(200).jsonp(result);
29+
returnresponse
30+
31+
})
32+
33+
});
34+
35+
exportdefaultapp;

‎backend/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import resetRoutes from './api/reset-routes';
66
importuserRoutesfrom'./api/user-routes';
77
importloginRoutesfrom'./api/login-routes';
88
importsignupRoutesfrom'./api/signup-routes';
9+
importlocationRoutesfrom'./api/location-routes';
910

1011
exportconststartServer=():PluginOption=>{
1112

@@ -36,6 +37,7 @@ export const startServer = (): PluginOption => {
3637
app.use('/cards',cardRoutes)
3738
app.use('/users',userRoutes)
3839
app.use('/reset',resetRoutes)
40+
app.use('/location',locationRoutes)
3941
app.use(middleware);
4042

4143
app.use(router);

‎cypress/e2e/board.spec.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,18 @@ it('board actions', () => {
8686

8787

8888
cy.step('shows network error when board are not loaded')
89-
cy.intercept('/api/boards',{
90-
forceNetworkError:true
89+
cy.intercept({
90+
url:'/api/boards',
91+
times:1
92+
},{
93+
statusCode:404
9194
})
9295
cy.reload()
9396
cy.getDataCy('board-list-error-message')
9497
.should('contain.text','There was an error loading your boards')
98+
99+
cy.contains('Try again').click()
100+
101+
cy.location('pathname').should('eq','/')
102+
cy.getDataCy('board-item').should('be.visible')
95103
});

‎cypress/e2e/cardDetail.spec.ts‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ it('card detail actions', function() {
2626
cy.getDataCy('card').click();
2727

2828
cy.step('card properties')
29-
cy.getDataCy('copy-properties').click();
30-
cy.task('getClipboard').should('eq',JSON.stringify(card,null,2));
29+
cy.getDataCy('copy-properties').realClick();
30+
cy.window().its('navigator.clipboard')
31+
.invoke('readText').should('eq',JSON.stringify(card,null,2));
3132
cy.getDataCy('notification-message')
3233
.should('exist')
3334
.and('contain.text','Card info copied to clipboard');
@@ -68,12 +69,10 @@ it('card detail actions', function() {
6869
cy.step('image upload')
6970
cy.intercept({
7071
method:'POST',
71-
url:'/api/upload',
72-
times:2
72+
url:'/api/upload?card=*',
7373
}).as('imageUpload');
7474
cy.getDataCy('upload-image').selectFile('cypress/fixtures/cypressLogo.png',{action:'drag-drop'});
75-
cy.wait('@imageUpload').its('response.body').should('have.property','path').and('not.be.empty');
76-
cy.wait('@updateCard').its('response.body.image').should('not.be.empty');
75+
cy.wait('@imageUpload').its('response.body').should('have.property','image').and('not.be.empty');
7776
cy.getDataCy('image-attachment').should('exist');
7877
cy.getDataCy('notification-message').should('exist').and('contain.text','File was sucessfully uploaded');
7978
cy.getDataCy('image-delete').click();
@@ -84,7 +83,7 @@ it('card detail actions', function() {
8483
cy.step('error when upload does not work')
8584
cy.intercept({
8685
method:'POST',
87-
url:'/api/upload'
86+
url:'/api/upload?card=*'
8887
},{
8988
statusCode:400
9089
}).as('imageUpload');

‎cypress/e2e/main.spec.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ describe('main page', () => {
1111
cy.visit('/board/9999999999');
1212
cy.getDataCy('board-list-error-message').should('be.visible');
1313

14+
cy.contains('Go back home').click()
15+
cy.location('pathname').should('eq','/')
16+
1417
cy.visit(`/board/${boardId}?card=1`);
1518
cy.getDataCy('notification-message').should('contain.text','Card with id: 1 was not found')
1619

‎cypress/e2e/pricing.spec.ts‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
it('shows pricing',()=>{
2+
3+
cy.intercept({
4+
method:'GET',
5+
url:'/api/location',
6+
times:1
7+
},{
8+
location:'us',
9+
currency:'USD',
10+
discountEligible:false
11+
}).as('locationUS')
12+
13+
cy.visit('/pricing')
14+
cy.wait('@locationUS')
15+
16+
cy.getDataCy('plan-item').eq(1).should('have.class','border-blue6')
17+
cy.getDataCy('plan-item').eq(0).click().should('have.class','border-blue6')
18+
cy.getDataCy('plan-item').eq(1).should('not.have.class','border-blue6')
19+
20+
// USD
21+
cy.getDataCy('plan-price').should('contain','$')
22+
23+
// GBP
24+
cy.intercept({
25+
method:'GET',
26+
url:'/api/location',
27+
times:1
28+
},{
29+
location:'uk',
30+
currency:'GBP',
31+
discountEligible:false
32+
}).as('locationUK')
33+
34+
35+
cy.reload()
36+
cy.wait('@locationUK')
37+
38+
cy.getDataCy('plan-price').should('contain','£')
39+
40+
// EUR
41+
cy.intercept({
42+
method:'GET',
43+
url:'/api/location',
44+
times:1
45+
},{
46+
location:'sk',
47+
currency:'EUR',
48+
discountEligible:true,
49+
discountAmount:20
50+
}).as('locationEU')
51+
52+
53+
cy.reload()
54+
cy.wait('@locationEU')
55+
56+
cy.getDataCy('plan-price').should('contain','€')
57+
cy.getDataCy('discount').should('be.visible').and('contain','20%')
58+
59+
});

‎cypress/e2e/search.spec.ts‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
beforeEach(()=>{
2+
cy.request('POST','/api/reset');
3+
cy.addBoardApi('new board').its('id').as('boardId')
4+
.addListApi({name:'new list'})
5+
.addCardApi({name:'new card'}).its('id').as('cardId');
6+
});
7+
8+
it('performs a card search',function(){
9+
10+
cy.visit('/')
11+
12+
cy.window().invoke('store').invoke('toggleSearch',true)
13+
14+
cy.getDataCy('search-input').type('new card')
15+
cy.getDataCy('result-item').contains('new card').click()
16+
17+
cy.location('href').should('include',`/board/${this.boardId}?card=${this.cardId}`)
18+
19+
cy.window().invoke('store').invoke('toggleSearch',true)
20+
cy.getDataCy('search-input').type('n')
21+
cy.getDataCy('result-item').should('be.visible')
22+
cy.getDataCy('search-input').type('{backspace}')
23+
24+
});

‎cypress/e2e/tools.spec.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('Tools', () => {
2929
cy.getDataCy('card').should('be.visible')
3030
cy.getDataCy('list').should('be.visible')
3131

32-
cy.get('body').click().realPress('F2')
32+
cy.window().trigger('keydown',{keyCode:113,which:113})
3333

3434
cy.getDataCy('api-tools')
3535
.should('be.visible')

‎cypress/support/@types/selectors.d.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export type Selectors =
3131
|'day'
3232
|'delete-board'
3333
|'delete-list'
34+
|'discount'
3435
|'due-date'
3536
|'error-icon'
3637
|'first-board'
@@ -58,6 +59,8 @@ export type Selectors =
5859
|'new-card'
5960
|'new-card-input'
6061
|'notification-message'
62+
|'plan-item'
63+
|'plan-price'
6164
|'result-item'
6265
|'search-input'
6366
|'signup-email'

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp