Skip to content

Commit 3fa39e2

Browse files
committed
React native app for crud on entries.
TODO: integrate aws cognito user pool. https://github.com/aws/amazon-cognito-identity-js
1 parent 67da929 commit 3fa39e2

File tree

151 files changed

+3790
-20
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+3790
-20
lines changed

README.md

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
# Graphql Lambda
22

3-
## Configure
4-
`cp config.example.json config.json`
3+
CRUD on an `Entry` object using aws lambdas triggered by API Gateway.
54

5+
## Configure
6+
`cp lambda/config.example.json lambda/config.json`
67

78
## Upload
8-
`zip -r ../graphqlAws.zip . && aws lambda update-function-code --function-name graphqlAws --zip-file fileb:///path/to/graphqlLambda.zip`
9+
`cd lambda && npm install && zip -r ../graphqlAws.zip . && aws lambda update-function-code --function-name graphqlAws --zip-file fileb:///path/to/graphqlLambda.zip`
910

1011
## Query
1112

1213
### health
13-
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" -d '{"query": "{ health }"}'`
14+
`curl -s -w \\n%{time_total}sec\\n -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" -d '{"query": "{ health }"}'`
1415
### add entry
15-
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @queries/addEntry.json | json_pp'`
16+
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @lambda/queries/addEntry.json | json_pp'`
1617

1718
### get entry
18-
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @queries/getEntry.json | json_pp'`
19+
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @lambda/queries/getEntry.json | json_pp'`
1920

2021
### get entries
21-
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @queries/getEntries.json | json_pp`
22+
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @lambda/queries/getEntries.json | json_pp`
2223

2324
### drop entry
24-
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @queries/dropEntry.json | json_pp'`
25+
`curl -v -H "Content-Type: application/json" "https://exl1b1c7fk.execute-api.us-west-2.amazonaws.com/dev/graphalAws" --data @lambda/queries/dropEntry.json | json_pp'`
26+
27+
## Launch App
28+
29+
`cd client && npm install && react-native run-ios`

client/.gitignore

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
project.xcworkspace
24+
25+
# Android/IntelliJ
26+
#
27+
build/
28+
.idea
29+
.gradle
30+
local.properties
31+
*.iml
32+
33+
# node.js
34+
#
35+
node_modules/
36+
npm-debug.log
37+
38+
# BUCK
39+
buck-out/
40+
\.buckd/
41+
android/app/libs
42+
*.keystore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
exports[`Android renders correctly 1`] = `
2+
<View
3+
style={
4+
Object {
5+
"backgroundColor": "rgba(0, 0, 0, 0.1)",
6+
"flex": 1,
7+
}
8+
}>
9+
<View
10+
style={
11+
Object {
12+
"alignItems": "center",
13+
"flex": 1,
14+
"justifyContent": "center",
15+
}
16+
}>
17+
<Text
18+
accessible={true}
19+
allowFontScaling={true}
20+
ellipsizeMode="tail">
21+
Loading cards...
22+
</Text>
23+
</View>
24+
</View>
25+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
exports[`iOS renders correctly 1`] = `
2+
<View
3+
style={
4+
Object {
5+
"backgroundColor": "rgba(0, 0, 0, 0.1)",
6+
"flex": 1,
7+
}
8+
}>
9+
<View
10+
style={
11+
Object {
12+
"alignItems": "center",
13+
"flex": 1,
14+
"justifyContent": "center",
15+
}
16+
}>
17+
<Text
18+
accessible={true}
19+
allowFontScaling={true}
20+
ellipsizeMode="tail">
21+
Loading cards...
22+
</Text>
23+
</View>
24+
</View>
25+
`;

client/__tests__/index.android.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'react-native';
2+
import React from 'react';
3+
import Index from '../index.android.js';
4+
import renderer from 'react-test-renderer';
5+
6+
describe('Android', () => {
7+
8+
it('renders correctly', () => {
9+
const tree = renderer.create(
10+
<Index />
11+
).toJSON();
12+
expect(tree).toMatchSnapshot();
13+
});
14+
15+
});

client/__tests__/index.ios.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'react-native';
2+
import React from 'react';
3+
import Index from '../index.ios.js';
4+
import renderer from 'react-test-renderer';
5+
6+
describe('iOS', () => {
7+
8+
it('renders correctly', () => {
9+
const tree = renderer.create(
10+
<Index />
11+
).toJSON();
12+
expect(tree).toMatchSnapshot();
13+
});
14+
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'react-native';
2+
import React from 'react';
3+
const EgressActions = require('../../../src/actions/EgressActions');
4+
const StateTree = require('../../../src/stores/StateTree').default;
5+
const ImgurAdapter = require('../../../src/adapters/ImgurAdapter').default;
6+
7+
describe('Egress Actions', () => {
8+
9+
beforeEach(() => {
10+
ImgurAdapter.getCards = jest.fn();
11+
});
12+
13+
it('can request cards', () => {
14+
expect(StateTree.get(['fetch', 'pending'])).toBe(false);
15+
EgressActions.requestCards();
16+
expect(ImgurAdapter.getCards).toHaveBeenCalled();
17+
expect(StateTree.get(['fetch', 'pending'])).toBe(true);
18+
});
19+
20+
it('does not request cards if they are already being fetched', () => {
21+
StateTree.set(['fetch', 'pending'], true);
22+
EgressActions.requestCards();
23+
expect(ImgurAdapter.getCards).not.toHaveBeenCalled();
24+
expect(StateTree.get(['fetch', 'pending'])).toBe(true);
25+
});
26+
27+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import 'react-native';
2+
import React from 'react';
3+
const IngressActions = require('../../../src/actions/IngressActions');
4+
const StateTree = require('../../../src/stores/StateTree').default;
5+
6+
const cards = [
7+
{
8+
link: 'http://example.com/1.webm',
9+
size: 1,
10+
'is_album': false
11+
},
12+
{
13+
link: 'http://example.com/2.webm',
14+
size: 1,
15+
'is_album': true
16+
},
17+
{
18+
link: 'http://example.com/3.webm',
19+
size: Math.pow(2, 24),
20+
'is_album': false
21+
}
22+
];
23+
24+
describe('Ingress Actions', () => {
25+
26+
it('can receive cards', () => {
27+
StateTree.set(['fetch', 'pending'], true);
28+
StateTree.set(['fetch', 'failed'], true);
29+
StateTree.set(['page'], 1);
30+
31+
IngressActions.receiveCards(cards);
32+
33+
expect(StateTree.get(['fetch', 'pending'])).toBe(false);
34+
expect(StateTree.get(['fetch', 'failed'])).toBe(false);
35+
expect(StateTree.get('page')).toBe(2);
36+
expect(StateTree.get('cards')).toEqual([{
37+
index: 0,
38+
key: 'card-1-0',
39+
large: 'https://example.com/1.webm',
40+
small: 'https://example.com/1m.webm',
41+
}]);
42+
});
43+
44+
it('can fail to receive cards', () => {
45+
StateTree.set(['fetch', 'pending'], true);
46+
StateTree.set(['fetch', 'failed'], false);
47+
48+
IngressActions.receiveCardsFailed();
49+
50+
expect(StateTree.get(['fetch', 'pending'])).toBe(false);
51+
expect(StateTree.get(['fetch', 'failed'])).toBe(true);
52+
});
53+
54+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'react-native';
2+
import React from 'react';
3+
import Card from '../../../src/components/Card.react';
4+
5+
import renderer from 'react-test-renderer';
6+
7+
it('renders correctly', () => {
8+
const tree = renderer.create(
9+
<Card />
10+
).toJSON();
11+
expect(tree).toMatchSnapshot();
12+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'react-native';
2+
import React from 'react';
3+
import Cards from '../../../src/components/Cards.react';
4+
const StateTree = require('../../../src/stores/StateTree').default;
5+
const EgressActions = require('../../../src/actions/EgressActions');
6+
import { shallow } from 'enzyme';
7+
import SwipeCards from 'react-native-swipe-cards';
8+
import Loading from '../../../src/components/Loading.react';
9+
10+
console.error = jest.fn();
11+
12+
describe('Cards', () => {
13+
14+
beforeEach(() => {
15+
EgressActions.requestCards = jest.fn();
16+
});
17+
18+
it('can render loading screen', () => {
19+
const context = {tree: StateTree};
20+
const wrapper = shallow(<Cards />, { context });
21+
expect(wrapper.render().find('text').text()).toEqual('Loading cards...');
22+
expect(EgressActions.requestCards).toHaveBeenCalled();
23+
});
24+
25+
it('can render card stack', () => {
26+
const cards = [
27+
{
28+
index: 0,
29+
key: 'card-1-0',
30+
large: 'https://example.com/1.webm',
31+
small: 'https://example.com/1m.webm',
32+
},
33+
{
34+
index: 1,
35+
key: 'card-1-1',
36+
large: 'https://example.com/2.webm',
37+
small: 'https://example.com/2m.webm',
38+
},
39+
{
40+
index: 2,
41+
key: 'card-1-2',
42+
large: 'https://example.com/3.webm',
43+
small: 'https://example.com/3m.webm',
44+
}
45+
];
46+
47+
StateTree.set('cards', cards);
48+
const context = {tree: StateTree};
49+
const wrapper = shallow(<Cards />, { context });
50+
51+
expect(EgressActions.requestCards).not.toHaveBeenCalled();
52+
expect(wrapper.render().find('image').length).toEqual(2);
53+
});
54+
55+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
exports[`test renders correctly 1`] = `
2+
<View
3+
style={
4+
Object {
5+
"alignItems": "center",
6+
"backgroundColor": "white",
7+
"borderColor": "rgba(0, 0, 0, 0.2)",
8+
"borderRadius": 4,
9+
"borderWidth": 1,
10+
"height": 1174,
11+
"justifyContent": "center",
12+
"marginLeft": 195,
13+
"marginTop": 30,
14+
"shadowColor": "rgba(0, 0, 0, 0.5)",
15+
"shadowOffset": Object {
16+
"height": 1,
17+
"width": 2,
18+
},
19+
"shadowOpacity": 1,
20+
"width": 360,
21+
}
22+
}>
23+
<Image
24+
onError={[Function]}
25+
resizeMode="contain"
26+
source={
27+
Object {
28+
"uri": "undefinedasdf",
29+
}
30+
}
31+
style={
32+
Object {
33+
"borderRadius": 5,
34+
"height": 320,
35+
"width": 320,
36+
}
37+
} />
38+
</View>
39+
`;

0 commit comments

Comments
 (0)