From 15ac4afa83a0aac2064fc405408beb749812ad73 Mon Sep 17 00:00:00 2001 From: ildar Date: Tue, 23 May 2023 22:55:56 +0600 Subject: [PATCH 1/8] fix: twitter mocking for test mode --- pnpm-lock.yaml | 298 ++++++++++++++++++++++++------------- src/actions/tweet.count.js | 3 + src/actions/tweet.get.js | 3 + src/actions/tweet.sync.js | 3 + 4 files changed, 205 insertions(+), 102 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 50b93da9..2fbdb4a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: '@hapi/hapi': ^20.2.1 @@ -65,21 +65,21 @@ specifiers: dependencies: '@hapi/hapi': 20.2.1 - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-amqp': 0.10.2_78d50cfeb91994eb3d0d763b4f7ae615 - '@microfleet/plugin-hapi': 0.10.2_93d17d26404461c7d567047ad53c521f - '@microfleet/plugin-knex': 2.26.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-opentracing': 0.13.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-prometheus': 0.13.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-router': 0.11.2_19a2f8a1bb41ea210972ba5d15d7812d - '@microfleet/plugin-router-amqp': 0.10.2_eff8ad6f94ccfbd07f90b2cb44a7092e - '@microfleet/plugin-router-hapi': 0.10.2_54fda05d9dc63868a129572355e1c9ba - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 + '@microfleet/plugin-amqp': 0.10.2_pdkqz7vzdgkowpinoy5u66xgcu + '@microfleet/plugin-hapi': 0.10.2_spix2jsairq4pvlhar5nkpcsd4 + '@microfleet/plugin-knex': 2.26.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-opentracing': 0.13.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-prometheus': 0.13.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-router': 0.11.2_dgrprin3ihvccclsxjorlv4bfu + '@microfleet/plugin-router-amqp': 0.10.2_574k234uzt55a74qwlfujjyjfy + '@microfleet/plugin-router-hapi': 0.10.2_kt62axm5yy4grijjk4rvlyojxi + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce '@microfleet/transport-amqp': 17.3.0_common-errors@1.2.0 '@microfleet/utils': 0.13.2 - '@microfleet/validation': 11.1.2 + '@microfleet/validation': 11.1.2_common-errors@1.2.0 '@sentry/node': 6.19.7 bluebird: 3.7.2 bn.js: 5.2.1 @@ -244,10 +244,10 @@ packages: '@types/node': 14.18.31 chalk: 4.1.2 cosmiconfig: 7.0.1 - cosmiconfig-typescript-loader: 4.1.1_33d7b64ae90e9bb80d48469351c457b9 + cosmiconfig-typescript-loader: 4.1.1_gpl3msxjb2n3qdkii2jvdrcxxe lodash: 4.17.21 resolve-from: 5.0.0 - ts-node: 10.9.1_2abc08acbb4fe741ae8218df9aa74f5c + ts-node: 10.9.1_fk6arlf3j7tudlucddpzvj2plq typescript: 4.8.4 transitivePeerDependencies: - '@swc/core' @@ -844,7 +844,7 @@ packages: eventemitter3: 4.0.7 dev: false - /@microfleet/core/17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c: + /@microfleet/core/17.29.2_7lr2vv5bl57san5n4sfdx2tkfq: resolution: {integrity: sha512-oG9/7PjO0I7/iRc0OBsmHy7rrKSJlxgZraKRnLhUQHkkG76BmrLXfvGc98I660UTcjF6mcnb3RBeBS/jJ91r6w==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} hasBin: true @@ -854,7 +854,7 @@ packages: dependencies: '@microfleet/core-types': 0.23.2 '@microfleet/utils': 0.23.2 - '@microfleet/validation': 11.1.2 + '@microfleet/validation': 11.1.2_common-errors@1.2.0 bluebird: 3.7.2 bluebird-retry: 0.11.0_bluebird@3.7.2 common-errors: 1.2.0 @@ -865,7 +865,7 @@ packages: - supports-color dev: false - /@microfleet/plugin-amqp/0.10.2_78d50cfeb91994eb3d0d763b4f7ae615: + /@microfleet/plugin-amqp/0.10.2_pdkqz7vzdgkowpinoy5u66xgcu: resolution: {integrity: sha512-cHWQG7deo9zRlJVmyX9t/hA9db6qFkwLY22AoPlrXhkYylw2g8xR57/J3eFXigbWVF87spHkiWASL+D7KYMBwQ==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: @@ -875,10 +875,10 @@ packages: '@microfleet/plugin-validator': ^0.13.2 common-errors: ~1.x.x dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-router': 0.11.2_19a2f8a1bb41ea210972ba5d15d7812d - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-router': 0.11.2_dgrprin3ihvccclsxjorlv4bfu + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce '@microfleet/transport-amqp': 17.3.0_common-errors@1.2.0 bluebird: 3.7.2 common-errors: 1.2.0 @@ -886,7 +886,7 @@ packages: - supports-color dev: false - /@microfleet/plugin-hapi/0.10.2_93d17d26404461c7d567047ad53c521f: + /@microfleet/plugin-hapi/0.10.2_spix2jsairq4pvlhar5nkpcsd4: resolution: {integrity: sha512-pz4u8DxH8TT98EXgufCuqhqS7Gs8lAURi3PZ42+hmBWc26fGJRvAQZiyaxn6Ni6U69dbpmecIEmAxaRGyDtAdQ==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: @@ -895,12 +895,12 @@ packages: dependencies: '@hapi/hapi': 20.2.1 '@hapi/vision': 6.1.0 - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-router': 0.11.2_19a2f8a1bb41ea210972ba5d15d7812d - '@microfleet/plugin-socketio': 0.10.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-router': 0.11.2_dgrprin3ihvccclsxjorlv4bfu + '@microfleet/plugin-socketio': 0.10.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce common-errors: 1.2.0 joi: 17.6.0 transitivePeerDependencies: @@ -910,17 +910,17 @@ packages: - utf-8-validate dev: false - /@microfleet/plugin-knex/2.26.2_3c4caf0d55a0947eb17902763ef1a99c: + /@microfleet/plugin-knex/2.26.2_hrgk6dkvuckh5mlzaj3d54njtq: resolution: {integrity: sha512-mZZuMtofRMyMh5/MSnk9rnoI7cRVZekXzatp7V/IRrFJVo5F7+XzSe0leBoHQz/hIEaaT9lPtMQ2OMzSNzu4Hg==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: '@microfleet/core': ^17.29.2 common-errors: ~1.x.x dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.23.2 - '@microfleet/plugin-logger': 0.28.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-validator': 0.23.2_90442f699ac3861d147f2a2fa22c190f + '@microfleet/plugin-logger': 0.28.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-validator': 0.23.2_sbcc62m2yodb2fd7fix2elazb4 '@microfleet/utils': 0.23.2 bluebird: 3.7.2 bluebird-retry: 0.11.0_bluebird@3.7.2 @@ -937,16 +937,16 @@ packages: - tedious dev: false - /@microfleet/plugin-logger/0.18.2_3c4caf0d55a0947eb17902763ef1a99c: + /@microfleet/plugin-logger/0.18.2_hrgk6dkvuckh5mlzaj3d54njtq: resolution: {integrity: sha512-E/dq4lFZtz+woE06y5ahjZvS7w+GTd0WLnZ3cCTEoCPxguz/o/VoTqfN0zJrnFhH0Ir0hEmpMFW2HfapLMSCrA==} engines: {node: '>= 12.15.0', npm: '>= 4.0.0'} peerDependencies: '@microfleet/core': ^17.19.2 common-errors: ~1.x.x dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce '@microfleet/utils': 0.13.2 '@sentry/utils': 6.19.2 common-errors: 1.2.0 @@ -960,16 +960,16 @@ packages: - supports-color dev: false - /@microfleet/plugin-logger/0.28.2_3c4caf0d55a0947eb17902763ef1a99c: + /@microfleet/plugin-logger/0.28.2_hrgk6dkvuckh5mlzaj3d54njtq: resolution: {integrity: sha512-PWzgKwrd2Qvh6HKa09HQOZrfWfQ2OAf9dn9No8Otzcq8HbwZetaMwbJm33A0vgzGx94/JEXwnjRX/u+Ragootw==} engines: {node: '>= 12.15.0', npm: '>= 4.0.0'} peerDependencies: '@microfleet/core': ^17.29.2 common-errors: ~1.x.x dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.23.2 - '@microfleet/plugin-validator': 0.23.2_90442f699ac3861d147f2a2fa22c190f + '@microfleet/plugin-validator': 0.23.2_sbcc62m2yodb2fd7fix2elazb4 '@microfleet/utils': 0.23.2 '@sentry/utils': 7.14.0 common-errors: 1.2.0 @@ -983,17 +983,17 @@ packages: - supports-color dev: false - /@microfleet/plugin-opentracing/0.13.2_3c4caf0d55a0947eb17902763ef1a99c: + /@microfleet/plugin-opentracing/0.13.2_hrgk6dkvuckh5mlzaj3d54njtq: resolution: {integrity: sha512-UFisO6mcIvflDZosaoiU0mACM/CQFBWK0JfWylB7dXrI7+DsPzfC76iOgi7QpKCC+x9Tc/EZRQajb1Cp/+9Ytw==} engines: {node: '>= 12.15.0', npm: '>= 4.0.0'} peerDependencies: '@microfleet/core': ^17.19.2 common-errors: ~1.x.x dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce '@microfleet/utils': 0.13.2 common-errors: 1.2.0 jaeger-client: 3.19.0 @@ -1001,14 +1001,14 @@ packages: - supports-color dev: false - /@microfleet/plugin-prometheus/0.13.2_3c4caf0d55a0947eb17902763ef1a99c: + /@microfleet/plugin-prometheus/0.13.2_hrgk6dkvuckh5mlzaj3d54njtq: resolution: {integrity: sha512-c3qqIMQS+qAYh0OxfBrFGInEE9kMpvBtz8E9iHrrYWdlG5B/1YpbbYa/9rOhd2OFmST3bgd4DN1wzatYXQ8Usw==} engines: {node: '>= 12.15.0', npm: '>= 4.0.0'} peerDependencies: '@microfleet/core': ^17.19.2 common-errors: ~1.x.x dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 '@microfleet/utils': 0.13.2 common-errors: 1.2.0 @@ -1016,7 +1016,7 @@ packages: semver: 7.3.5 dev: false - /@microfleet/plugin-router-amqp/0.10.2_eff8ad6f94ccfbd07f90b2cb44a7092e: + /@microfleet/plugin-router-amqp/0.10.2_574k234uzt55a74qwlfujjyjfy: resolution: {integrity: sha512-qavW9SCNquovA0z1VtST7/N3+U2K14N+Q04hlNIYUcK9PdInEvgBEIBAjI1E4g/lwbuPo/JJgygNzwxZFzh9WA==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: @@ -1028,11 +1028,11 @@ packages: common-errors: ~1.x.x dependencies: '@microfleet/amqp-coffee': 2.3.2 - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-amqp': 0.10.2_78d50cfeb91994eb3d0d763b4f7ae615 - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-router': 0.11.2_19a2f8a1bb41ea210972ba5d15d7812d + '@microfleet/plugin-amqp': 0.10.2_pdkqz7vzdgkowpinoy5u66xgcu + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-router': 0.11.2_dgrprin3ihvccclsxjorlv4bfu '@microfleet/transport-amqp': 17.3.0_common-errors@1.2.0 bluebird: 3.7.2 common-errors: 1.2.0 @@ -1041,7 +1041,7 @@ packages: - supports-color dev: false - /@microfleet/plugin-router-hapi/0.10.2_54fda05d9dc63868a129572355e1c9ba: + /@microfleet/plugin-router-hapi/0.10.2_kt62axm5yy4grijjk4rvlyojxi: resolution: {integrity: sha512-GJOr55qe1q9nTmsgnp5fDNzawDDjhyFAG1r/rVvPndNRUmMlUg8nKVudBUGFD1OvjC6h9fEsqLIaphQ7z6kUtw==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: @@ -1054,12 +1054,12 @@ packages: dependencies: '@hapi/boom': 9.1.4 '@hapi/hapi': 20.2.1 - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c - '@microfleet/plugin-hapi': 0.10.2_93d17d26404461c7d567047ad53c521f - '@microfleet/plugin-opentracing': 0.13.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-router': 0.11.2_19a2f8a1bb41ea210972ba5d15d7812d - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 - '@microfleet/validation': 11.1.2 + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq + '@microfleet/plugin-hapi': 0.10.2_spix2jsairq4pvlhar5nkpcsd4 + '@microfleet/plugin-opentracing': 0.13.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-router': 0.11.2_dgrprin3ihvccclsxjorlv4bfu + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce + '@microfleet/validation': 11.1.2_common-errors@1.2.0 common-errors: 1.2.0 get-value: 3.0.1 lodash: 4.17.21 @@ -1068,7 +1068,7 @@ packages: - supports-color dev: false - /@microfleet/plugin-router/0.11.2_19a2f8a1bb41ea210972ba5d15d7812d: + /@microfleet/plugin-router/0.11.2_dgrprin3ihvccclsxjorlv4bfu: resolution: {integrity: sha512-IWr/aIEl6RVDplP4rdEGjm9JiGp8Hak++08wbyA8xLA1HXknaxxYKR/MLVEr/MvbYDqoZZpUp1G+G3xhw7Qb7w==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: @@ -1079,12 +1079,12 @@ packages: common-errors: ~1.x.x dependencies: '@hapi/boom': 9.1.4 - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq '@microfleet/transport-amqp': 17.3.0_common-errors@1.2.0 '@microfleet/utils': 0.13.2 - '@microfleet/validation': 11.1.2 + '@microfleet/validation': 11.1.2_common-errors@1.2.0 common-errors: 1.2.0 glob: 7.2.3 hyperid: 3.0.1 @@ -1096,7 +1096,7 @@ packages: - supports-color dev: false - /@microfleet/plugin-socketio/0.10.2_3c4caf0d55a0947eb17902763ef1a99c: + /@microfleet/plugin-socketio/0.10.2_hrgk6dkvuckh5mlzaj3d54njtq: resolution: {integrity: sha512-+kEFsPhZMZLMLEWBwQ9gJP0Tn93pXGhL7j9UG/2WADyMvdgTOvpy65L15Z3o+QHCvw0/2znBNJzuZAEKAUnWUw==} engines: {node: '>= 12.14.0', npm: '>= 4.0.0'} peerDependencies: @@ -1104,15 +1104,15 @@ packages: common-errors: ~1.x.x dependencies: '@microfleet/amqp-coffee': 2.3.2 - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 - '@microfleet/plugin-logger': 0.18.2_3c4caf0d55a0947eb17902763ef1a99c - '@microfleet/plugin-router': 0.11.2_19a2f8a1bb41ea210972ba5d15d7812d - '@microfleet/plugin-validator': 0.13.2_66a43bd8e31e900c76384eac644f1611 + '@microfleet/plugin-logger': 0.18.2_hrgk6dkvuckh5mlzaj3d54njtq + '@microfleet/plugin-router': 0.11.2_dgrprin3ihvccclsxjorlv4bfu + '@microfleet/plugin-validator': 0.13.2_m2sdxwhdd2iay5ryj2wgitywce '@microfleet/transport-amqp': 17.3.0_common-errors@1.2.0 '@microfleet/utils': 0.13.2 common-errors: 1.2.0 - ms-socket.io-adapter-amqp: 9.0.1_00e1ea48190344393d2e80d9a9511e14 + ms-socket.io-adapter-amqp: 9.0.1_adq6usazancdspjoqdm2sui6cq socket.io: 4.4.1 transitivePeerDependencies: - bufferutil @@ -1120,7 +1120,7 @@ packages: - utf-8-validate dev: false - /@microfleet/plugin-validator/0.13.2_66a43bd8e31e900c76384eac644f1611: + /@microfleet/plugin-validator/0.13.2_m2sdxwhdd2iay5ryj2wgitywce: resolution: {integrity: sha512-MT+PkpkpnesORM84LFiq5+fIeic79IQlP/bKVm1J+GZ+qiBxXAnhuHP+NZMuQM1lh+tx64UIU3dihUCND7VMuw==} engines: {node: '>= 12.15.0', npm: '>= 4.0.0'} peerDependencies: @@ -1128,10 +1128,10 @@ packages: '@microfleet/core-types': ^0.13.2 '@microfleet/utils': ^0.13.2 dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 '@microfleet/utils': 0.13.2 - '@microfleet/validation': 11.1.2 + '@microfleet/validation': 11.1.2_common-errors@1.2.0 callsite: 1.0.0 common-errors: 1.2.0 lodash: 4.17.21 @@ -1139,7 +1139,7 @@ packages: - supports-color dev: false - /@microfleet/plugin-validator/0.23.2_90442f699ac3861d147f2a2fa22c190f: + /@microfleet/plugin-validator/0.23.2_sbcc62m2yodb2fd7fix2elazb4: resolution: {integrity: sha512-WOonHY6c+sDje40TOn+f/ExEpDrBGiIBbJcOMLx3c1IChMCkK0IYCl/DLaSvNvWwS/2HZcJLzg2R40DLClJ0+Q==} engines: {node: '>= 12.15.0', npm: '>= 4.0.0'} peerDependencies: @@ -1147,10 +1147,10 @@ packages: '@microfleet/core-types': ^0.23.2 '@microfleet/utils': ^0.23.2 dependencies: - '@microfleet/core': 17.29.2_fae3aad7a15f7f2037ade48a3bea6a2c + '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.23.2 '@microfleet/utils': 0.23.2 - '@microfleet/validation': 11.1.2 + '@microfleet/validation': 11.1.2_common-errors@1.2.0 callsite: 1.0.0 common-errors: 1.2.0 lodash: 4.17.21 @@ -1204,9 +1204,11 @@ packages: read-pkg-up: 7.0.1 dev: false - /@microfleet/validation/11.1.2: + /@microfleet/validation/11.1.2_common-errors@1.2.0: resolution: {integrity: sha512-UAytvgv18PAFyrFHUlgdNlfElygLkohuupirJjSS4tQqIJrV95w7zdWYAhpnqW07M02IwVaATKz6oGOv/tjgmA==} engines: {node: '>= 14.15.0', npm: '>= 4.x.x'} + peerDependencies: + common-errors: ~1.x.x dependencies: ajv: 8.11.0 ajv-formats: 2.1.1 @@ -1800,7 +1802,7 @@ packages: '@types/node': 18.7.23 dev: false - /@typescript-eslint/eslint-plugin/5.17.0_7e65682680cffeace60e7661702716fb: + /@typescript-eslint/eslint-plugin/5.17.0_pzswqjuaz77kzzqoozqxajyw7m: resolution: {integrity: sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1811,10 +1813,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.17.0_eslint@8.6.0+typescript@4.8.4 + '@typescript-eslint/parser': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 '@typescript-eslint/scope-manager': 5.17.0 - '@typescript-eslint/type-utils': 5.17.0_eslint@8.6.0+typescript@4.8.4 - '@typescript-eslint/utils': 5.17.0_eslint@8.6.0+typescript@4.8.4 + '@typescript-eslint/type-utils': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 + '@typescript-eslint/utils': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 debug: 4.3.4 eslint: 8.6.0 functional-red-black-tree: 1.0.1 @@ -1827,7 +1829,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.17.0_eslint@8.6.0+typescript@4.8.4: + /@typescript-eslint/parser/5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4: resolution: {integrity: sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1855,7 +1857,7 @@ packages: '@typescript-eslint/visitor-keys': 5.17.0 dev: true - /@typescript-eslint/type-utils/5.17.0_eslint@8.6.0+typescript@4.8.4: + /@typescript-eslint/type-utils/5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4: resolution: {integrity: sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1865,7 +1867,7 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.17.0_eslint@8.6.0+typescript@4.8.4 + '@typescript-eslint/utils': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 debug: 4.3.4 eslint: 8.6.0 tsutils: 3.21.0_typescript@4.8.4 @@ -1900,7 +1902,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.17.0_eslint@8.6.0+typescript@4.8.4: + /@typescript-eslint/utils/5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4: resolution: {integrity: sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2036,7 +2038,7 @@ packages: '@xtuc/long': 4.2.2 dev: true - /@webpack-cli/configtest/1.1.1_webpack-cli@4.9.2+webpack@5.70.0: + /@webpack-cli/configtest/1.1.1_spmstbzrmxjdafr7ccogoqrx6e: resolution: {integrity: sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==} peerDependencies: webpack: 4.x.x || 5.x.x @@ -2744,6 +2746,8 @@ packages: escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.3.0 + transitivePeerDependencies: + - supports-color dev: true /chrome-remote-interface/0.31.3: @@ -2999,8 +3003,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - is-text-path: 1.0.1 JSONStream: 1.3.5 + is-text-path: 1.0.1 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -3039,7 +3043,7 @@ packages: vary: 1.1.2 dev: false - /cosmiconfig-typescript-loader/4.1.1_33d7b64ae90e9bb80d48469351c457b9: + /cosmiconfig-typescript-loader/4.1.1_gpl3msxjb2n3qdkii2jvdrcxxe: resolution: {integrity: sha512-9DHpa379Gp0o0Zefii35fcmuuin6q92FnLDffzdZ0l9tVd3nEobG3O+MZ06+kuBvFTSVScvNb/oHA13Nd4iipg==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -3050,7 +3054,7 @@ packages: dependencies: '@types/node': 14.18.31 cosmiconfig: 7.0.1 - ts-node: 10.9.1_2abc08acbb4fe741ae8218df9aa74f5c + ts-node: 10.9.1_fk6arlf3j7tudlucddpzvj2plq typescript: 4.8.4 dev: true @@ -3126,15 +3130,37 @@ packages: /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: ms: 2.0.0 dev: true /debug/3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: ms: 2.1.3 + /debug/3.2.7_supports-color@5.5.0: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 5.5.0 + dev: true + /debug/4.3.3_supports-color@8.1.1: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -3368,7 +3394,7 @@ packages: resolution: {integrity: sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==} engines: {node: '>=10.13.0'} dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 tapable: 2.2.1 dev: true @@ -3689,7 +3715,7 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-airbnb-base/15.0.0_b5a36b8c1535387c8dd00eff7ec6b551: + /eslint-config-airbnb-base/15.0.0_wwrwxdavgu4hzdoqb37x5rvvke: resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -3698,7 +3724,7 @@ packages: dependencies: confusing-browser-globals: 1.0.11 eslint: 8.6.0 - eslint-plugin-import: 2.25.4_eslint@8.6.0 + eslint-plugin-import: 2.25.4_iqw3drkeu3ex4nvrz5kovrx4yq object.assign: 4.1.2 object.entries: 1.1.5 semver: 6.3.0 @@ -3707,14 +3733,16 @@ packages: /eslint-config-makeomatic/5.1.0_typescript@4.8.4: resolution: {integrity: sha512-CZt/arn15KqCPM+YLfv5BwLkHrgjIUaRKMcnB9kJ/cBos3eP49GRKBPmi7XCEMDo4+68gVvKcgPUzffVQjVDqA==} dependencies: - '@typescript-eslint/eslint-plugin': 5.17.0_7e65682680cffeace60e7661702716fb - '@typescript-eslint/parser': 5.17.0_eslint@8.6.0+typescript@4.8.4 + '@typescript-eslint/eslint-plugin': 5.17.0_pzswqjuaz77kzzqoozqxajyw7m + '@typescript-eslint/parser': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 eslint: 8.6.0 - eslint-config-airbnb-base: 15.0.0_b5a36b8c1535387c8dd00eff7ec6b551 - eslint-plugin-import: 2.25.4_eslint@8.6.0 + eslint-config-airbnb-base: 15.0.0_wwrwxdavgu4hzdoqb37x5rvvke + eslint-plugin-import: 2.25.4_iqw3drkeu3ex4nvrz5kovrx4yq eslint-plugin-promise: 6.0.0_eslint@8.6.0 eslint-plugin-unicorn: 40.1.0_eslint@8.6.0 transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack - supports-color - typescript dev: true @@ -3724,29 +3752,79 @@ packages: dependencies: debug: 3.2.7 resolve: 1.22.0 + transitivePeerDependencies: + - supports-color dev: true - /eslint-module-utils/2.7.3: + /eslint-module-utils/2.7.3_aomysh6w35sl7gbuoze27zteb4: resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true dependencies: + '@typescript-eslint/parser': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 debug: 3.2.7 + eslint-import-resolver-node: 0.3.6 + find-up: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils/2.7.3_ulu2225r2ychl26a37c6o2rfje: + resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + debug: 3.2.7 + eslint-import-resolver-node: 0.3.6 find-up: 2.1.0 + transitivePeerDependencies: + - supports-color dev: true - /eslint-plugin-import/2.25.4_eslint@8.6.0: + /eslint-plugin-import/2.25.4_iqw3drkeu3ex4nvrz5kovrx4yq: resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} engines: {node: '>=4'} peerDependencies: + '@typescript-eslint/parser': '*' eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true dependencies: + '@typescript-eslint/parser': 5.17.0_oqhpifbdsnl6ewfwbkgh6fckz4 array-includes: 3.1.4 array.prototype.flat: 1.2.5 debug: 2.6.9 doctrine: 2.1.0 eslint: 8.6.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3 + eslint-module-utils: 2.7.3_aomysh6w35sl7gbuoze27zteb4 has: 1.0.3 is-core-module: 2.8.1 is-glob: 4.0.3 @@ -3754,13 +3832,21 @@ packages: object.values: 1.1.5 resolve: 1.22.0 tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color dev: true /eslint-plugin-import/2.26.0_eslint@8.24.0: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: + '@typescript-eslint/parser': '*' eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true dependencies: array-includes: 3.1.4 array.prototype.flat: 1.2.5 @@ -3768,7 +3854,7 @@ packages: doctrine: 2.1.0 eslint: 8.24.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3 + eslint-module-utils: 2.7.3_ulu2225r2ychl26a37c6o2rfje has: 1.0.3 is-core-module: 2.8.1 is-glob: 4.0.3 @@ -3776,6 +3862,10 @@ packages: object.values: 1.1.5 resolve: 1.22.0 tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color dev: true /eslint-plugin-json/3.1.0: @@ -5339,7 +5429,7 @@ packages: dependencies: universalify: 2.0.0 optionalDependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 dev: true /jsonparse/1.3.1: @@ -5468,6 +5558,8 @@ packages: dependencies: debug: 2.6.9 marky: 1.2.5 + transitivePeerDependencies: + - supports-color dev: true /lines-and-columns/1.2.4: @@ -5848,7 +5940,7 @@ packages: transitivePeerDependencies: - supports-color - /ms-socket.io-adapter-amqp/9.0.1_00e1ea48190344393d2e80d9a9511e14: + /ms-socket.io-adapter-amqp/9.0.1_adq6usazancdspjoqdm2sui6cq: resolution: {integrity: sha512-sGaFwgPpnOZY4O5WhWLD4SKMPKSYTKF6AAFbw8Nf5mLRq1CBm837O6XKPWCR8dcO8wJvHqqamOfL7oGfrfRBlQ==} peerDependencies: '@microfleet/amqp-coffee': '>= 2' @@ -5966,7 +6058,7 @@ packages: requiresBuild: true dependencies: chokidar: 3.5.3 - debug: 3.2.7 + debug: 3.2.7_supports-color@5.5.0 ignore-by-default: 1.0.1 minimatch: 3.1.2 pstree.remy: 1.1.8 @@ -6859,6 +6951,8 @@ packages: resolution: {integrity: sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==} dependencies: debug: 3.2.7 + transitivePeerDependencies: + - supports-color dev: false /regexp-tree/0.1.24: @@ -7723,7 +7817,7 @@ packages: resolution: {integrity: sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==} dev: true - /ts-node/10.9.1_2abc08acbb4fe741ae8218df9aa74f5c: + /ts-node/10.9.1_fk6arlf3j7tudlucddpzvj2plq: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -8034,7 +8128,7 @@ packages: engines: {node: '>=10.13.0'} dependencies: glob-to-regexp: 0.4.1 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 dev: true /webidl-conversions/3.0.1: @@ -8062,7 +8156,7 @@ packages: optional: true dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 1.1.1_webpack-cli@4.9.2+webpack@5.70.0 + '@webpack-cli/configtest': 1.1.1_spmstbzrmxjdafr7ccogoqrx6e '@webpack-cli/info': 1.4.1_webpack-cli@4.9.2 '@webpack-cli/serve': 1.6.1_webpack-cli@4.9.2 colorette: 2.0.16 diff --git a/src/actions/tweet.count.js b/src/actions/tweet.count.js index f42a5cba..c9442792 100644 --- a/src/actions/tweet.count.js +++ b/src/actions/tweet.count.js @@ -8,6 +8,9 @@ const { ActionTransport } = require('@microfleet/plugin-router'); * @apiSchema {jsonschema=../../schemas/tweet.count.json} apiParam */ async function TweetCountAction({ params }) { + if ( process.env.TEST_MODE ) { + return { data: 0 } + } const data = await this.service('feed') .countByAccounts(params.data); return { data }; diff --git a/src/actions/tweet.get.js b/src/actions/tweet.get.js index 6290f82d..a6bd9d99 100644 --- a/src/actions/tweet.get.js +++ b/src/actions/tweet.get.js @@ -9,6 +9,9 @@ const { modelResponse, TYPE_TWEET } = require('../utils/response'); * @apiSchema {jsonschema=../../schemas/tweet.sync.json} apiParam */ function TweetGetAction({ params }) { + if ( process.env.TEST_MODE ) { + return { data: null } + } return this .service('feed') .getOne(params) diff --git a/src/actions/tweet.sync.js b/src/actions/tweet.sync.js index 870aff0d..1276f249 100644 --- a/src/actions/tweet.sync.js +++ b/src/actions/tweet.sync.js @@ -9,6 +9,9 @@ const { modelResponse, TYPE_TWEET } = require('../utils/response'); * @apiSchema {jsonschema=../../schemas/tweet.sync.json} apiParam */ function TweetSyncAction({ params }) { + if ( process.env.TEST_MODE ) { + return { data: null } + } return this .service('feed') .syncOne(params) From 14399619d566cb5daa8c8f45b1f218dc080ddd2b Mon Sep 17 00:00:00 2001 From: ildar Date: Thu, 25 May 2023 12:09:24 +0600 Subject: [PATCH 2/8] fix: test mode mock for twitter --- package.json | 1 + pnpm-lock.yaml | 21 +- src/actions/tweet.count.js | 3 - src/actions/tweet.get.js | 3 - src/actions/tweet.sync.js | 3 - src/services/twitter/intercepts/index.js | 740 +++++++++++++++++++++++ src/social.js | 5 + test/docker-compose.yml | 1 + test/suites/twitter.filter.js | 6 +- 9 files changed, 772 insertions(+), 11 deletions(-) create mode 100644 src/services/twitter/intercepts/index.js diff --git a/package.json b/package.json index e1d1753c..5b18b813 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "lodash": "^4.17.21", "moment": "^2.29.4", "ms-conf": "^7.0.2", + "nock": "^13.3.1", "p-limit": "3", "pg": "^8.8.0", "pino": "^7.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2fbdb4a1..9e1d4bbc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,7 @@ specifiers: mocha: ^9.2.2 moment: ^2.29.4 ms-conf: ^7.0.2 + nock: ^13.3.1 p-limit: '3' pg: ^8.8.0 pino: ^7.11.0 @@ -91,6 +92,7 @@ dependencies: lodash: 4.17.21 moment: 2.29.4 ms-conf: 7.0.2 + nock: 13.3.1 p-limit: 3.1.0 pg: 8.8.0 pino: 7.11.0 @@ -5399,7 +5401,7 @@ packages: dev: true /json-stringify-safe/5.0.1: - resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} /json/11.0.0: resolution: {integrity: sha512-N/ITv3Yw9Za8cGxuQqSqrq6RHnlaHWZkAFavcfpH/R52522c26EbihMxnY7A1chxfXJ4d+cEFIsyTgfi9GihrA==} @@ -6012,6 +6014,18 @@ packages: path-to-regexp: 1.8.0 dev: true + /nock/13.3.1: + resolution: {integrity: sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==} + engines: {node: '>= 10.13'} + dependencies: + debug: 4.3.4 + json-stringify-safe: 5.0.1 + lodash: 4.17.21 + propagate: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: false + /node-addon-api/1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} dev: true @@ -6739,6 +6753,11 @@ packages: tdigest: 0.1.1 dev: false + /propagate/2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + dev: false + /proxy-addr/2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} diff --git a/src/actions/tweet.count.js b/src/actions/tweet.count.js index c9442792..f42a5cba 100644 --- a/src/actions/tweet.count.js +++ b/src/actions/tweet.count.js @@ -8,9 +8,6 @@ const { ActionTransport } = require('@microfleet/plugin-router'); * @apiSchema {jsonschema=../../schemas/tweet.count.json} apiParam */ async function TweetCountAction({ params }) { - if ( process.env.TEST_MODE ) { - return { data: 0 } - } const data = await this.service('feed') .countByAccounts(params.data); return { data }; diff --git a/src/actions/tweet.get.js b/src/actions/tweet.get.js index a6bd9d99..6290f82d 100644 --- a/src/actions/tweet.get.js +++ b/src/actions/tweet.get.js @@ -9,9 +9,6 @@ const { modelResponse, TYPE_TWEET } = require('../utils/response'); * @apiSchema {jsonschema=../../schemas/tweet.sync.json} apiParam */ function TweetGetAction({ params }) { - if ( process.env.TEST_MODE ) { - return { data: null } - } return this .service('feed') .getOne(params) diff --git a/src/actions/tweet.sync.js b/src/actions/tweet.sync.js index 1276f249..870aff0d 100644 --- a/src/actions/tweet.sync.js +++ b/src/actions/tweet.sync.js @@ -9,9 +9,6 @@ const { modelResponse, TYPE_TWEET } = require('../utils/response'); * @apiSchema {jsonschema=../../schemas/tweet.sync.json} apiParam */ function TweetSyncAction({ params }) { - if ( process.env.TEST_MODE ) { - return { data: null } - } return this .service('feed') .syncOne(params) diff --git a/src/services/twitter/intercepts/index.js b/src/services/twitter/intercepts/index.js new file mode 100644 index 00000000..91a9f883 --- /dev/null +++ b/src/services/twitter/intercepts/index.js @@ -0,0 +1,740 @@ +const nock = require('nock'); +const url = require('url'); +const debug = require('debug'); + +const log = debug('twitter:intercept'); + +function createUser(screenName) { + return { + id: 2533316504, + id_str: '2533316504', + name: 'random name', + screen_name: screenName, + location: 'Vancouver, British Columbia', + description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', + url: null, + entities: { + description: { + urls: [], + }, + }, + protected: false, + followers_count: 105, + friends_count: 157, + listed_count: 3, + created_at: 'Thu May 29 20:07:42 +0000 2014', + favourites_count: 59, + utc_offset: null, + time_zone: null, + geo_enabled: true, + verified: false, + statuses_count: 146, + lang: null, + status: { + created_at: 'Tue Feb 07 00:32:46 +0000 2023', + id: 1622755209964568576, + id_str: '1622755209964568576', + text: '@mikeal @nodejs Would love to go. Nostalgic vibes with similar outdoor activities :)', + truncated: false, + entities: { + hashtags: [], + symbols: [], + user_mentions: [ + { + screen_name: 'mikeal', + name: 'Mikeal Rogers', + id: 668423, + id_str: '668423', + indices: [ + 0, + 7, + ], + }, + { + screen_name: 'nodejs', + name: 'Node.js', + id: 91985735, + id_str: '91985735', + indices: [ + 8, + 15, + ], + }, + ], + urls: [], + }, + source: 'Twitter for iPhone', + in_reply_to_status_id: 1622624107270664192, + in_reply_to_status_id_str: '1622624107270664192', + in_reply_to_user_id: 668423, + in_reply_to_user_id_str: '668423', + in_reply_to_screen_name: 'mikeal', + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 0, + favorite_count: 2, + favorited: false, + retweeted: false, + lang: 'en', + }, + contributors_enabled: false, + is_translator: false, + is_translation_enabled: false, + profile_background_color: 'C0DEED', + profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_tile: false, + profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', + profile_link_color: '000000', + profile_sidebar_border_color: 'C0DEED', + profile_sidebar_fill_color: 'DDEEF6', + profile_text_color: '333333', + profile_use_background_image: true, + has_extended_profile: false, + default_profile: false, + default_profile_image: false, + following: false, + follow_request_sent: false, + notifications: false, + translator_type: 'none', + withheld_in_countries: [], + suspended: false, + needs_phone_verification: false, + }; +} + +function createTwitStatusObjectMock( + screenName, + options = { reply: false } +) { + return { + created_at: 'Wed Oct 10 20:19:24 +0000 2018', + id: 1050118621198921728, + id_str: '1050118621198921728', + text: 'To make room for more expression, we will now count all ' + + 'emojis as equal—including those with gender‍‍‍ and skin t… https://t.co/MkGjXf9aXm', + truncated: true, + entities: { + hashtags: [], + symbols: [], + user_mentions: [], + urls: [ + { + url: 'https://t.co/MkGjXf9aXm', + expanded_url: 'https://twitter.com/i/web/status/1050118621198921728', + display_url: 'twitter.com/i/web/status/1…', + indices: [ + 117, + 140, + ], + }, + ], + }, + source: 'Twitter Web Client', + user: { + id: 1, + id_str: '1', + name: 'Twitter API', + screen_name: screenName, + location: 'San Francisco, CA', + description: 'The Real Twitter API. Tweets about API changes, service issues and ' + + "our Developer Platform. Don't get an answer? It's on my website.", + url: 'https://t.co/8IkCzCDr19', + entities: { + url: { + urls: [ + { + url: 'https://t.co/8IkCzCDr19', + expanded_url: 'https://developer.twitter.com', + display_url: 'developer.twitter.com', + indices: [ + 0, + 23, + ], + }, + ], + }, + description: { + urls: [], + }, + }, + protected: false, + followers_count: 6128663, + friends_count: 12, + listed_count: 12900, + created_at: 'Wed May 23 06:01:13 +0000 2007', + favourites_count: 32, + utc_offset: null, + time_zone: null, + geo_enabled: null, + verified: true, + statuses_count: 3659, + lang: 'null', + contributors_enabled: null, + is_translator: null, + is_translation_enabled: null, + profile_background_color: 'null', + profile_background_image_url: 'null', + profile_background_image_url_https: 'null', + profile_background_tile: null, + profile_image_url: 'null', + profile_image_url_https: 'https://pbs.twimg.com/profile_images/942858479592554497/BbazLO9L_normal.jpg', + profile_banner_url: 'https://pbs.twimg.com/profile_banners/6253282/1497491515', + profile_link_color: 'null', + profile_sidebar_border_color: 'null', + profile_sidebar_fill_color: 'null', + profile_text_color: 'null', + profile_use_background_image: null, + has_extended_profile: null, + default_profile: false, + default_profile_image: false, + following: null, + follow_request_sent: null, + notifications: null, + translator_type: 'null', + }, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 161, + favorite_count: 296, + favorited: false, + retweeted: false, + possibly_sensitive: false, + possibly_sensitive_appealable: false, + lang: 'en', + ...options.reply ? { + in_reply_to_status_id: null, + in_reply_to_status_id_str: null, + in_reply_to_user_id: 1, + in_reply_to_user_id_str: null, + in_reply_to_screen_name: null, + } : {}, + }; +} + +function createReply() { + return { + created_at: 'Sat Oct 15 17:50:29 +0000 2016', + // eslint-disable-next-line no-loss-of-precision + id: 787349945225515008, + id_str: '787349945225515008', + text: '@NodeConfEU team @MakeOmatic is in Dublin. Heading to get some dinner soon, any1 who wants to join is very welcome :)', + truncated: false, + entities: { + hashtags: [], + symbols: [], + user_mentions: [ + { + screen_name: 'NodeConfEU', + name: 'NodeConf EU Nov 6th-8th 2023', + id: 526867353, + id_str: '526867353', + indices: [ + 0, + 11, + ], + }, + { + screen_name: 'MakeOmatic', + name: 'makeomatic', + id: 1960663927, + id_str: '1960663927', + indices: [ + 17, + 28, + ], + }, + ], + urls: [], + }, + source: 'Twitter Web Client', + // eslint-disable-next-line no-loss-of-precision + in_reply_to_status_id: 1621960453323735041, + in_reply_to_status_id_str: '1621960453323735041', + in_reply_to_user_id: 356087317, + in_reply_to_user_id_str: '356087317', + in_reply_to_screen_name: 's_gimeno', + user: { + id: 2533316504, + id_str: '2533316504', + name: 'Vitaly Aminev @ Vancouver 🇨🇦', + screen_name: 'v_aminev', + location: 'Vancouver, British Columbia', + description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', + url: null, + entities: { + description: { + urls: [], + }, + }, + protected: false, + followers_count: 105, + friends_count: 157, + listed_count: 3, + created_at: 'Thu May 29 20:07:42 +0000 2014', + favourites_count: 59, + utc_offset: null, + time_zone: null, + geo_enabled: true, + verified: false, + statuses_count: 146, + lang: null, + contributors_enabled: false, + is_translator: false, + is_translation_enabled: false, + profile_background_color: 'C0DEED', + profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_tile: false, + profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', + profile_link_color: '000000', + profile_sidebar_border_color: 'C0DEED', + profile_sidebar_fill_color: 'DDEEF6', + profile_text_color: '333333', + profile_use_background_image: true, + has_extended_profile: false, + default_profile: false, + default_profile_image: false, + following: false, + follow_request_sent: false, + notifications: false, + translator_type: 'none', + withheld_in_countries: [], + }, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 1, + favorite_count: 1, + favorited: false, + retweeted: false, + lang: 'en', + }; +} + +function createOriginal() { + return { + created_at: 'Sat Oct 15 17:50:29 +0000 2016', + // eslint-disable-next-line no-loss-of-precision + id: 787349945225515001, + id_str: '787349945225515001', + text: '@NodeConfEU team @MakeOmatic is in Dublin. Heading to get some dinner soon, any1 who wants to join is very welcome :)', + truncated: false, + entities: { + hashtags: [], + symbols: [], + user_mentions: [ + { + screen_name: 'NodeConfEU', + name: 'NodeConf EU Nov 6th-8th 2023', + id: 526867353, + id_str: '526867353', + indices: [ + 0, + 11, + ], + }, + { + screen_name: 'MakeOmatic', + name: 'makeomatic', + id: 1960663927, + id_str: '1960663927', + indices: [ + 17, + 28, + ], + }, + ], + urls: [], + }, + source: 'Twitter Web Client', + // "in_reply_to_status_id": null, + // "in_reply_to_status_id_str": null, + // "in_reply_to_user_id": null, + // "in_reply_to_user_id_str": null, + // "in_reply_to_screen_name": null, + user: { + id: 2533316504, + id_str: '2533316504', + name: 'Vitaly Aminev @ Vancouver 🇨🇦', + screen_name: 'v_aminev', + location: 'Vancouver, British Columbia', + description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', + url: null, + entities: { + description: { + urls: [], + }, + }, + protected: false, + followers_count: 105, + friends_count: 157, + listed_count: 3, + created_at: 'Thu May 29 20:07:42 +0000 2014', + favourites_count: 59, + utc_offset: null, + time_zone: null, + geo_enabled: true, + verified: false, + statuses_count: 146, + lang: null, + contributors_enabled: false, + is_translator: false, + is_translation_enabled: false, + profile_background_color: 'C0DEED', + profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_tile: false, + profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', + profile_link_color: '000000', + profile_sidebar_border_color: 'C0DEED', + profile_sidebar_fill_color: 'DDEEF6', + profile_text_color: '333333', + profile_use_background_image: true, + has_extended_profile: false, + default_profile: false, + default_profile_image: false, + following: false, + follow_request_sent: false, + notifications: false, + translator_type: 'none', + withheld_in_countries: [], + }, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 1, + favorite_count: 1, + favorited: false, + retweeted: false, + lang: 'en', + }; +} + +function createRetweet() { + return { + created_at: 'Tue Jan 31 22:17:00 +0000 2023', + // eslint-disable-next-line no-loss-of-precision + id: 1620546716373254144, + id_str: '1620546716373254144', + text: 'RT @amineva_art: •Making mixed #media #artwork by playing around with its background. Fisrt #NFT ' + + 'collection drops soon•\n#digitalart #nftcol…', + truncated: false, + entities: { + hashtags: [ + { + text: 'media', + indices: [ + 31, + 37, + ], + }, + { + text: 'artwork', + indices: [ + 38, + 46, + ], + }, + { + text: 'NFT', + indices: [ + 92, + 96, + ], + }, + { + text: 'digitalart', + indices: [ + 120, + 131, + ], + }, + ], + symbols: [], + user_mentions: [ + { + screen_name: 'amineva_art', + name: 'Anya', + id: 271456488, + id_str: '271456488', + indices: [ + 3, + 15, + ], + }, + ], + urls: [], + }, + source: 'Twitter for iPhone', + in_reply_to_status_id: null, + in_reply_to_status_id_str: null, + in_reply_to_user_id: null, + in_reply_to_user_id_str: null, + in_reply_to_screen_name: null, + user: { + id: 2533316504, + id_str: '2533316504', + name: 'Vitaly Aminev @ Vancouver 🇨🇦', + screen_name: 'v_aminev', + location: 'Vancouver, British Columbia', + description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', + url: null, + entities: { + description: { + urls: [], + }, + }, + protected: false, + followers_count: 105, + friends_count: 157, + listed_count: 3, + created_at: 'Thu May 29 20:07:42 +0000 2014', + favourites_count: 59, + utc_offset: null, + time_zone: null, + geo_enabled: true, + verified: false, + statuses_count: 146, + lang: null, + contributors_enabled: false, + is_translator: false, + is_translation_enabled: false, + profile_background_color: 'C0DEED', + profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_tile: false, + profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', + profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', + profile_link_color: '000000', + profile_sidebar_border_color: 'C0DEED', + profile_sidebar_fill_color: 'DDEEF6', + profile_text_color: '333333', + profile_use_background_image: true, + has_extended_profile: false, + default_profile: false, + default_profile_image: false, + following: false, + follow_request_sent: false, + notifications: false, + translator_type: 'none', + withheld_in_countries: [], + }, + geo: null, + coordinates: null, + place: null, + contributors: null, + retweeted_status: { + created_at: 'Fri Jan 27 02:00:01 +0000 2023', + // eslint-disable-next-line no-loss-of-precision + id: 1618790903912480768, + id_str: '1618790903912480768', + text: '•Making mixed #media #artwork by playing around with its background. ' + + 'Fisrt #NFT collection drops soon•\n#digitalart… https://t.co/te1xkATUVG', + truncated: true, + entities: { + hashtags: [ + { + text: 'media', + indices: [ + 14, + 20, + ], + }, + { + text: 'artwork', + indices: [ + 21, + 29, + ], + }, + { + text: 'NFT', + indices: [ + 75, + 79, + ], + }, + { + text: 'digitalart', + indices: [ + 103, + 114, + ], + }, + ], + symbols: [], + user_mentions: [], + urls: [ + { + url: 'https://t.co/te1xkATUVG', + expanded_url: 'https://twitter.com/i/web/status/1618790903912480768', + display_url: 'twitter.com/i/web/status/1…', + indices: [ + 116, + 139, + ], + }, + ], + }, + source: 'FeedHive', + in_reply_to_status_id: null, + in_reply_to_status_id_str: null, + in_reply_to_user_id: null, + in_reply_to_user_id_str: null, + in_reply_to_screen_name: null, + user: { + id: 271456488, + id_str: '271456488', + name: 'Anya', + screen_name: 'amineva_art', + location: 'Vancouver', + description: 'NFT artist / Illustrator / Painter / Animator. In love with digital creatures. ' + + 'Design Evangelist / Founder at https://t.co/GtOcuhBqNf 🇨🇦 Instagram: @amineva_art', + url: null, + entities: { + description: { + urls: [ + { + url: 'https://t.co/GtOcuhBqNf', + expanded_url: 'http://Makeomatic.ca', + display_url: 'Makeomatic.ca', + indices: [ + 110, + 133, + ], + }, + ], + }, + }, + protected: false, + followers_count: 94, + friends_count: 88, + listed_count: 3, + created_at: 'Thu Mar 24 15:00:47 +0000 2011', + favourites_count: 55, + utc_offset: null, + time_zone: null, + geo_enabled: true, + verified: false, + statuses_count: 549, + lang: null, + contributors_enabled: false, + is_translator: false, + is_translation_enabled: false, + profile_background_color: '0A0A0A', + profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', + profile_background_tile: true, + profile_image_url: 'http://pbs.twimg.com/profile_images/1577656071539363845/9cBL_BeW_normal.jpg', + profile_image_url_https: 'https://pbs.twimg.com/profile_images/1577656071539363845/9cBL_BeW_normal.jpg', + profile_banner_url: 'https://pbs.twimg.com/profile_banners/271456488/1541105104', + profile_link_color: '2B59B5', + profile_sidebar_border_color: 'FFFFFF', + profile_sidebar_fill_color: 'EADEAA', + profile_text_color: '333333', + profile_use_background_image: true, + has_extended_profile: false, + default_profile: false, + default_profile_image: false, + following: true, + follow_request_sent: false, + notifications: false, + translator_type: 'none', + withheld_in_countries: [], + }, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 1, + favorite_count: 9, + favorited: true, + retweeted: true, + possibly_sensitive: false, + lang: 'en', + }, + is_quote_status: false, + retweet_count: 1, + favorite_count: 0, + favorited: true, + retweeted: true, + lang: 'en', + }; +} + +function interceptTwitterApi() { + log('using twitter api interceptor'); + nock.disableNetConnect() + nock('https://api.twitter.com') + .persist() + .get((uri) => { + log(`getting request for uri=${uri}`); + return uri.includes('users/lookup'); + }) + .reply(function (uri, requestBody) { + log('checkin users/lookup'); + const q = url.parse(uri, true); + log(`Intercepted GET request to: ${uri}`); + log('Request body: ', requestBody); + log(`query:${JSON.stringify(q.query)}`); + return [200, [createUser(q.query.screen_name)]]; + }); + + nock('https://api.twitter.com') + .persist() + .get((uri) => { + log(`getting request for uri=${uri}`); + return uri.includes('statuses/user_timeline'); + }) + .reply(function (uri, requestBody) { + log('checkin statuses/user_timeline'); + const q = url.parse(uri, true); + log(`Intercepted GET request to: ${uri}`); + log('Request body: ', requestBody); + log(`query:${JSON.stringify(q.query)}`); + const response = [ + createOriginal(), + createReply(), + createRetweet(), + ]; + return [200, response]; + }); + + nock('https://api.twitter.com') + .persist() + .get((uri) => { + log(1, () => `getting request for uri=${uri}`); + return uri.includes('statuses/show'); + }) + .reply(function (uri, requestBody) { + log('checkin statuses/show'); + const q = url.parse(uri, true); + log(`Intercepted GET request to: ${uri}`); + log('Request body: ', requestBody); + log(`query:${JSON.stringify(q.query)}`); + return [200, createTwitStatusObjectMock('v_aminev')]; + }); +} + +module.exports = { + interceptTwitterApi, +}; diff --git a/src/social.js b/src/social.js index 331eff2a..5dd7ce1e 100755 --- a/src/social.js +++ b/src/social.js @@ -11,9 +11,14 @@ const Facebook = require('./services/facebook'); const Notifier = require('./services/notifier'); const Instagram = require('./services/instagram'); const addUpsert = require('./utils/knex/upsert'); +const { interceptTwitterApi } = require('./services/twitter/intercepts'); const services = new WeakMap(); +if (process.env.TEST_MODE) { + interceptTwitterApi(); +} + class Social extends Microfleet { static defaultConfig = conf.get('/', { env: process.env.NODE_ENV, diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 71a3723f..ae6ba18b 100755 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -28,3 +28,4 @@ services: NODE_ENV: "test" DEBUG: ${DEBUG} NCONF_NAMESPACE: MS_SOCIAL + TEST_MODE: ${TEST_MODE} diff --git a/test/suites/twitter.filter.js b/test/suites/twitter.filter.js index 04af3166..41771657 100644 --- a/test/suites/twitter.filter.js +++ b/test/suites/twitter.filter.js @@ -4,7 +4,11 @@ const assert = require('assert'); const filterByType = (tweets, type) => tweets.filter((x) => Number.parseInt(x.attributes.type, 10) === type); [ - [true, [true, true], [0, 1, 2], []], + [true, + /* filters */ [true, true], + /* expectedTypes */ [0, 1, 2], + /* filteredTypes */ [], + ], [false, [true, true], [0], []], // check filteredTypes more correctly with own later ].forEach(([ignoreFilters, filters, expectedTypes, filteredTypes]) => { describe('twitter filter statuses', function testSuite() { From df8b7c457983446c1a20a7b2057855879e9e94d3 Mon Sep 17 00:00:00 2001 From: ildar Date: Thu, 25 May 2023 16:41:20 +0600 Subject: [PATCH 3/8] fix: fake account generators --- package.json | 2 + pnpm-lock.yaml | 26 + .../data/evgenypoyarkov/original.json | 102 +++ .../intercepts/data/evgenypoyarkov/reply.json | 102 +++ .../data/evgenypoyarkov/retweet.json | 212 ++++++ .../data/evgenypoyarkov/tweets.json | 5 + .../intercepts/data/evgenypoyarkov/user.json | 52 ++ .../intercepts/data/v_aminev/original.json | 102 +++ .../intercepts/data/v_aminev/reply.json | 102 +++ .../intercepts/data/v_aminev/retweet.json | 212 ++++++ .../intercepts/data/v_aminev/tweets.json | 5 + .../intercepts/data/v_aminev/user.json | 52 ++ .../twitter/intercepts/generator/cli.js | 27 + .../twitter/intercepts/generator/factories.js | 44 ++ .../intercepts/generator/models/mentions.js | 26 + .../intercepts/generator/models/original.js | 38 + .../intercepts/generator/models/reply.js | 39 + .../intercepts/generator/models/retweet.js | 68 ++ .../intercepts/generator/models/status.js | 56 ++ .../intercepts/generator/models/user.js | 58 ++ .../twitter/intercepts/generator/util.js | 26 + src/services/twitter/intercepts/index.js | 702 +----------------- src/social.js | 2 +- test/docker-compose.yml | 2 +- 24 files changed, 1374 insertions(+), 688 deletions(-) create mode 100644 src/services/twitter/intercepts/data/evgenypoyarkov/original.json create mode 100644 src/services/twitter/intercepts/data/evgenypoyarkov/reply.json create mode 100644 src/services/twitter/intercepts/data/evgenypoyarkov/retweet.json create mode 100644 src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json create mode 100644 src/services/twitter/intercepts/data/evgenypoyarkov/user.json create mode 100644 src/services/twitter/intercepts/data/v_aminev/original.json create mode 100644 src/services/twitter/intercepts/data/v_aminev/reply.json create mode 100644 src/services/twitter/intercepts/data/v_aminev/retweet.json create mode 100644 src/services/twitter/intercepts/data/v_aminev/tweets.json create mode 100644 src/services/twitter/intercepts/data/v_aminev/user.json create mode 100644 src/services/twitter/intercepts/generator/cli.js create mode 100644 src/services/twitter/intercepts/generator/factories.js create mode 100644 src/services/twitter/intercepts/generator/models/mentions.js create mode 100644 src/services/twitter/intercepts/generator/models/original.js create mode 100644 src/services/twitter/intercepts/generator/models/reply.js create mode 100644 src/services/twitter/intercepts/generator/models/retweet.js create mode 100644 src/services/twitter/intercepts/generator/models/status.js create mode 100644 src/services/twitter/intercepts/generator/models/user.js create mode 100644 src/services/twitter/intercepts/generator/util.js diff --git a/package.json b/package.json index 5b18b813..5881910c 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "prepare": "mdep install || true" }, "dependencies": { + "@faker-js/faker": "^8.0.1", "@hapi/hapi": "^20.2.1", "@microfleet/core": "^17.29.2", "@microfleet/core-types": "^0.13.2", @@ -46,6 +47,7 @@ "pg": "^8.8.0", "pino": "^7.11.0", "prom-client": "^14.1.0", + "randomstring": "^1.2.3", "request": "^2.88.2", "request-promise": "^4.2.6", "retry": "^0.13.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e1d4bbc..e01cc147 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,7 @@ lockfileVersion: 5.4 specifiers: + '@faker-js/faker': ^8.0.1 '@hapi/hapi': ^20.2.1 '@makeomatic/deploy': ^12.8.2 '@microfleet/core': ^17.29.2 @@ -53,6 +54,7 @@ specifiers: pg: ^8.8.0 pino: ^7.11.0 prom-client: ^14.1.0 + randomstring: ^1.2.3 request: ^2.88.2 request-promise: ^4.2.6 retry: ^0.13.1 @@ -65,6 +67,7 @@ specifiers: yargs: ^17.5.1 dependencies: + '@faker-js/faker': 8.0.1 '@hapi/hapi': 20.2.1 '@microfleet/core': 17.29.2_7lr2vv5bl57san5n4sfdx2tkfq '@microfleet/core-types': 0.13.2 @@ -97,6 +100,7 @@ dependencies: pg: 8.8.0 pino: 7.11.0 prom-client: 14.1.0 + randomstring: 1.2.3 request: 2.88.2 request-promise: 4.2.6_request@2.88.2 retry: 0.13.1 @@ -377,6 +381,11 @@ packages: - supports-color dev: true + /@faker-js/faker/8.0.1: + resolution: {integrity: sha512-kbh5MenpTN9U0B4QcOI1NoTPlZHniSYQ3BHbhAnPjJGAmmFqxoxTE4sGdpy7ZOO9038DPGCuhXyMkjOr05uVwA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} + dev: false + /@fastify/accept-negotiator/1.0.0: resolution: {integrity: sha512-4R/N2KfYeld7A5LGkai+iUFMahXcxxYbDp+XS2B1yuL3cdmZLJ9TlCnNzT3q5xFTqsYm0GPpinLUwfSwjcVjyA==} engines: {node: '>=14'} @@ -2363,6 +2372,11 @@ packages: engines: {node: '>=8'} dev: true + /array-uniq/1.0.2: + resolution: {integrity: sha512-GVYjmpL05al4dNlKJm53mKE4w9OOLiuVHWorsIA3YVz+Hu0hcn6PtE3Ydl0EqU7v+7ABC4mjjWsnLUxbpno+CA==} + engines: {node: '>=0.10.0'} + dev: false + /array.prototype.flat/1.2.5: resolution: {integrity: sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==} engines: {node: '>= 0.4'} @@ -6840,12 +6854,24 @@ packages: resolution: {integrity: sha512-Wswj8ZvzdI3VhaGPkZAxaCTwuMmGtgWt7Zxsgyo4P+iTmVnkojvyWaOep5q3ZjMIecW0wtQa66GWxaKkZ24RAA==} dev: true + /randombytes/2.0.3: + resolution: {integrity: sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==} + dev: false + /randombytes/2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: true + /randomstring/1.2.3: + resolution: {integrity: sha512-3dEFySepTzp2CvH6W/ASYGguPPveBuz5MpZ7MuoUkoVehmyNl9+F9c9GFVrz2QPbM9NXTIHGcmJDY/3j4677kQ==} + hasBin: true + dependencies: + array-uniq: 1.0.2 + randombytes: 2.0.3 + dev: false + /rc/1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true diff --git a/src/services/twitter/intercepts/data/evgenypoyarkov/original.json b/src/services/twitter/intercepts/data/evgenypoyarkov/original.json new file mode 100644 index 00000000..37942193 --- /dev/null +++ b/src/services/twitter/intercepts/data/evgenypoyarkov/original.json @@ -0,0 +1,102 @@ +{ + "created_at": "Thu May 25 10:38:58 +0000 2023", + "id": 146595, + "id_str": "146595", + "text": "Accusamus laboriosam incidunt neque maxime recusandae natus aperiam molestiae hic.", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 20743, + "id_str": "20743", + "name": "Bill Crooks", + "screen_name": "evgenypoyarkov", + "location": "French Guiana, Michealport", + "description": "Regional", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:38:58 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/evgenypoyarkov/reply.json b/src/services/twitter/intercepts/data/evgenypoyarkov/reply.json new file mode 100644 index 00000000..a1f457ff --- /dev/null +++ b/src/services/twitter/intercepts/data/evgenypoyarkov/reply.json @@ -0,0 +1,102 @@ +{ + "created_at": "Thu May 25 10:38:58 +0000 2023", + "id": 231653, + "id_str": "231653", + "text": "Nemo possimus dolor sit facilis eum occaecati error rem ab.", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": 622616, + "in_reply_to_status_id_str": "622616", + "in_reply_to_user_id": 596867, + "in_reply_to_user_id_str": "596867", + "in_reply_to_screen_name": "other_user", + "user": { + "id": 20743, + "id_str": "20743", + "name": "Bill Crooks", + "screen_name": "evgenypoyarkov", + "location": "French Guiana, Michealport", + "description": "Regional", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:38:58 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/evgenypoyarkov/retweet.json b/src/services/twitter/intercepts/data/evgenypoyarkov/retweet.json new file mode 100644 index 00000000..5c1d1dda --- /dev/null +++ b/src/services/twitter/intercepts/data/evgenypoyarkov/retweet.json @@ -0,0 +1,212 @@ +{ + "created_at": "Thu May 25 10:38:58 +0000 2023", + "id": 97762, + "id_str": "97762", + "text": "Optio illum modi ad voluptas totam necessitatibus molestiae esse nostrum.", + "truncated": false, + "entities": { + "hashtags": [ + { + "text": "media", + "indices": [ + 31, + 37 + ] + }, + { + "text": "artwork", + "indices": [ + 38, + 46 + ] + }, + { + "text": "NFT", + "indices": [ + 92, + 96 + ] + }, + { + "text": "digitalart", + "indices": [ + 120, + 131 + ] + } + ], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter for iPhone", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 20743, + "id_str": "20743", + "name": "Bill Crooks", + "screen_name": "evgenypoyarkov", + "location": "French Guiana, Michealport", + "description": "Regional", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:38:58 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "retweeted_status": { + "created_at": "Thu May 25 10:38:58 +0000 2023", + "id": 789210, + "id_str": "789210", + "text": "Modi non iste ut sed exercitationem eveniet est dignissimos delectus.", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 908973, + "id_str": "908973", + "name": "Yolanda Donnelly", + "screen_name": "retweet_user", + "location": "Portugal, Coconut Creek", + "description": "Forward", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:38:58 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" + }, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 0, + "favorited": true, + "retweeted": true, + "lang": "en" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json b/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json new file mode 100644 index 00000000..ced32226 --- /dev/null +++ b/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json @@ -0,0 +1,5 @@ +{ + "146595.json": "original.json", + "97762.json": "retweet.json", + "231653.json": "reply.json" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/evgenypoyarkov/user.json b/src/services/twitter/intercepts/data/evgenypoyarkov/user.json new file mode 100644 index 00000000..0c33181d --- /dev/null +++ b/src/services/twitter/intercepts/data/evgenypoyarkov/user.json @@ -0,0 +1,52 @@ +{ + "id": 20743, + "id_str": "20743", + "name": "Bill Crooks", + "screen_name": "evgenypoyarkov", + "location": "French Guiana, Michealport", + "description": "Regional", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:38:58 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/v_aminev/original.json b/src/services/twitter/intercepts/data/v_aminev/original.json new file mode 100644 index 00000000..daba432c --- /dev/null +++ b/src/services/twitter/intercepts/data/v_aminev/original.json @@ -0,0 +1,102 @@ +{ + "created_at": "Thu May 25 10:32:11 +0000 2023", + "id": 904549, + "id_str": "904549", + "text": "Cumque sunt vero quisquam repellat quo rerum illum odit explicabo.", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 532079, + "id_str": "532079", + "name": "Dr. Erik Haag", + "screen_name": "v_aminev", + "location": "Guinea-Bissau, Riverton", + "description": "National", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:32:11 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/v_aminev/reply.json b/src/services/twitter/intercepts/data/v_aminev/reply.json new file mode 100644 index 00000000..011ac91a --- /dev/null +++ b/src/services/twitter/intercepts/data/v_aminev/reply.json @@ -0,0 +1,102 @@ +{ + "created_at": "Thu May 25 10:32:11 +0000 2023", + "id": 991460, + "id_str": "991460", + "text": "Atque libero sunt iure doloremque qui eveniet officia delectus perferendis.", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": 522309, + "in_reply_to_status_id_str": "522309", + "in_reply_to_user_id": 296461, + "in_reply_to_user_id_str": "296461", + "in_reply_to_screen_name": "other_user", + "user": { + "id": 532079, + "id_str": "532079", + "name": "Dr. Erik Haag", + "screen_name": "v_aminev", + "location": "Guinea-Bissau, Riverton", + "description": "National", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:32:11 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/v_aminev/retweet.json b/src/services/twitter/intercepts/data/v_aminev/retweet.json new file mode 100644 index 00000000..e2850b1a --- /dev/null +++ b/src/services/twitter/intercepts/data/v_aminev/retweet.json @@ -0,0 +1,212 @@ +{ + "created_at": "Thu May 25 10:32:11 +0000 2023", + "id": 772961, + "id_str": "772961", + "text": "Recusandae aperiam omnis aliquam distinctio quo consectetur reiciendis laboriosam natus.", + "truncated": false, + "entities": { + "hashtags": [ + { + "text": "media", + "indices": [ + 31, + 37 + ] + }, + { + "text": "artwork", + "indices": [ + 38, + 46 + ] + }, + { + "text": "NFT", + "indices": [ + 92, + 96 + ] + }, + { + "text": "digitalart", + "indices": [ + 120, + 131 + ] + } + ], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter for iPhone", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 532079, + "id_str": "532079", + "name": "Dr. Erik Haag", + "screen_name": "v_aminev", + "location": "Guinea-Bissau, Riverton", + "description": "National", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:32:11 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "retweeted_status": { + "created_at": "Thu May 25 10:32:11 +0000 2023", + "id": 727355, + "id_str": "727355", + "text": "Aut laboriosam vero hic similique alias ducimus expedita architecto maiores.", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 986455, + "id_str": "986455", + "name": "Trevor Homenick", + "screen_name": "retweet_user", + "location": "Saint Barthelemy, North Genesischester", + "description": "Product", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:32:11 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" + }, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 0, + "favorited": true, + "retweeted": true, + "lang": "en" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/v_aminev/tweets.json b/src/services/twitter/intercepts/data/v_aminev/tweets.json new file mode 100644 index 00000000..1785e11a --- /dev/null +++ b/src/services/twitter/intercepts/data/v_aminev/tweets.json @@ -0,0 +1,5 @@ +{ + "904549.json": "original.json", + "772961.json": "retweet.json", + "991460.json": "reply.json" +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/data/v_aminev/user.json b/src/services/twitter/intercepts/data/v_aminev/user.json new file mode 100644 index 00000000..2d9f6117 --- /dev/null +++ b/src/services/twitter/intercepts/data/v_aminev/user.json @@ -0,0 +1,52 @@ +{ + "id": 532079, + "id_str": "532079", + "name": "Dr. Erik Haag", + "screen_name": "v_aminev", + "location": "Guinea-Bissau, Riverton", + "description": "National", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:32:11 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false +} \ No newline at end of file diff --git a/src/services/twitter/intercepts/generator/cli.js b/src/services/twitter/intercepts/generator/cli.js new file mode 100644 index 00000000..254ab572 --- /dev/null +++ b/src/services/twitter/intercepts/generator/cli.js @@ -0,0 +1,27 @@ +const fs = require("fs"); +const { userFactory, originalFactory, replyFactory, retweetFactory } = require("./factories"); + +const screenName = "evgenypoyarkov" +const user = userFactory(screenName) +const retweet = retweetFactory(user) +const original = originalFactory(user) +const reply = replyFactory(user) + +const tweets = {} +tweets[`${original.id}.json`] = "original.json" +tweets[`${retweet.id}.json`] = "retweet.json" +tweets[`${reply.id}.json`] = "reply.json" + +console.log(user) +console.log(original) +console.log(reply) +console.log(retweet) +console.log(tweets) + +fs.mkdirSync(__dirname + `/../data/${screenName}`); +fs.writeFileSync(__dirname + `/../data/${screenName}/user.json`, JSON.stringify(user, null, 2)) +fs.writeFileSync(__dirname + `/../data/${screenName}/original.json`, JSON.stringify(original, null, 2)) +fs.writeFileSync(__dirname + `/../data/${screenName}/reply.json`, JSON.stringify(reply, null, 2)) +fs.writeFileSync(__dirname + `/../data/${screenName}/retweet.json`, JSON.stringify(retweet, null, 2)) +fs.writeFileSync(__dirname + `/../data/${screenName}/tweets.json`, JSON.stringify(tweets, null, 2)) + diff --git a/src/services/twitter/intercepts/generator/factories.js b/src/services/twitter/intercepts/generator/factories.js new file mode 100644 index 00000000..ef7fd2ea --- /dev/null +++ b/src/services/twitter/intercepts/generator/factories.js @@ -0,0 +1,44 @@ + + +const createOriginal = require('./models/original') +const createStatus = require('./models/status') +const createReply = require('./models/reply') +const createRetweet = require('./models/retweet') +const createUser = require('./models/user') +const createMentions = require('./models/mentions') + +function retweetFactory(user) { + const otherUser = createUser("retweet_user") + const tweet = createOriginal(otherUser, []) + const mentions = createMentions() + return createRetweet(user, mentions, tweet) +} + +function replyFactory(user) { + const otherUser = createUser("other_user") + const tweet = createOriginal(otherUser, []) + const mentions = createMentions() + return createReply(user, mentions, tweet) +} + +function originalFactory(user) { + const mentions = createMentions() + return createOriginal(user, mentions) +} + +function statusFactory(user) { + const mentions = createMentions() + return createStatus(user, mentions) +} + +function userFactory(screenName) { + return createUser(screenName) +} + +module.exports = { + userFactory, + retweetFactory, + replyFactory, + originalFactory, + statusFactory +} diff --git a/src/services/twitter/intercepts/generator/models/mentions.js b/src/services/twitter/intercepts/generator/models/mentions.js new file mode 100644 index 00000000..d3fd0208 --- /dev/null +++ b/src/services/twitter/intercepts/generator/models/mentions.js @@ -0,0 +1,26 @@ + + +module.exports = function() { + return [ + { + screen_name: 'NodeConfEU', + name: 'NodeConf EU Nov 6th-8th 2023', + id: 526867353, + id_str: '526867353', + indices: [ + 0, + 11, + ], + }, + { + screen_name: 'MakeOmatic', + name: 'makeomatic', + id: 1960663927, + id_str: '1960663927', + indices: [ + 17, + 28, + ], + }, + ] +} diff --git a/src/services/twitter/intercepts/generator/models/original.js b/src/services/twitter/intercepts/generator/models/original.js new file mode 100644 index 00000000..84d134f3 --- /dev/null +++ b/src/services/twitter/intercepts/generator/models/original.js @@ -0,0 +1,38 @@ + +const { getRandomInt, getDateString } = require("../util"); +const { faker } = require("@faker-js/faker"); + +module.exports = function(user, mentions) { + const id = getRandomInt() + return { + created_at: getDateString(), + // eslint-disable-next-line no-loss-of-precision + id: id, + id_str: `${id}`, + text: faker.lorem.sentence(10), + truncated: false, + entities: { + hashtags: [], + symbols: [], + user_mentions: mentions, + urls: [], + }, + source: 'Twitter Web Client', + in_reply_to_status_id: null, + in_reply_to_status_id_str: null, + in_reply_to_user_id: null, + in_reply_to_user_id_str: null, + in_reply_to_screen_name: null, + user: user, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 1, + favorite_count: 1, + favorited: false, + retweeted: false, + lang: 'en', + }; +} diff --git a/src/services/twitter/intercepts/generator/models/reply.js b/src/services/twitter/intercepts/generator/models/reply.js new file mode 100644 index 00000000..5e0bdbfa --- /dev/null +++ b/src/services/twitter/intercepts/generator/models/reply.js @@ -0,0 +1,39 @@ + +const { getRandomInt, getDateString } = require("../util"); +const { faker } = require("@faker-js/faker"); + +module.exports = function(user, mentions = [], tweet) { + const id = getRandomInt() + return { + created_at: getDateString(), + // eslint-disable-next-line no-loss-of-precision + id: id, + id_str: `${id}`, + text: faker.lorem.sentence(10), + truncated: false, + entities: { + hashtags: [], + symbols: [], + user_mentions: mentions, + urls: [], + }, + source: 'Twitter Web Client', + // eslint-disable-next-line no-loss-of-precision + in_reply_to_status_id: tweet.id, + in_reply_to_status_id_str: `${tweet.id}`, + in_reply_to_user_id: tweet.user.id, + in_reply_to_user_id_str: `${tweet.user.id}`, + in_reply_to_screen_name: tweet.user.screen_name, + user: user, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 1, + favorite_count: 1, + favorited: false, + retweeted: false, + lang: 'en', + }; +} diff --git a/src/services/twitter/intercepts/generator/models/retweet.js b/src/services/twitter/intercepts/generator/models/retweet.js new file mode 100644 index 00000000..737d900b --- /dev/null +++ b/src/services/twitter/intercepts/generator/models/retweet.js @@ -0,0 +1,68 @@ + +const { getRandomInt, getDateString } = require("../util"); +const { faker } = require("@faker-js/faker"); + +module.exports = function(user, mentions, tweet) { + const id = getRandomInt() + return { + created_at: getDateString(), + // eslint-disable-next-line no-loss-of-precision + id: id, + id_str: `${id}`, + text: faker.lorem.sentence(10), + truncated: false, + entities: { + hashtags: [ + { + text: 'media', + indices: [ + 31, + 37, + ], + }, + { + text: 'artwork', + indices: [ + 38, + 46, + ], + }, + { + text: 'NFT', + indices: [ + 92, + 96, + ], + }, + { + text: 'digitalart', + indices: [ + 120, + 131, + ], + }, + ], + symbols: [], + user_mentions: mentions, + urls: [], + }, + source: 'Twitter for iPhone', + in_reply_to_status_id: null, + in_reply_to_status_id_str: null, + in_reply_to_user_id: null, + in_reply_to_user_id_str: null, + in_reply_to_screen_name: null, + user: user, + geo: null, + coordinates: null, + place: null, + contributors: null, + retweeted_status: tweet, + is_quote_status: false, + retweet_count: 1, + favorite_count: 0, + favorited: true, + retweeted: true, + lang: 'en', + }; +} diff --git a/src/services/twitter/intercepts/generator/models/status.js b/src/services/twitter/intercepts/generator/models/status.js new file mode 100644 index 00000000..691ee672 --- /dev/null +++ b/src/services/twitter/intercepts/generator/models/status.js @@ -0,0 +1,56 @@ +const { getRandomInt } = require("../util"); +const { faker } = require("@faker-js/faker"); + +module.exports = function(user, mentions) { + const id = getRandomInt() + return { + created_at: "Wed Jun 06 20:07:10 +0000 2012", + id: id, + id_str: `${id}`, + text: faker.lorem.sentence(10), + truncated: false, + entities: { + hashtags: [ + { + text: "Twitterbird", + indices: [ + 19, + 31 + ] + } + ], + symbols: [], + user_mentions: mentions, + urls: [ + { + url: "https://t.co/Ed4omjYs", + expanded_url: "https://dev.twitter.com/terms/display-guidelines", + display_url: "dev.twitter.com/terms/display-…", + indices: [ + 76, + 97 + ] + } + ] + }, + source: "Twitter Web Client", + in_reply_to_status_id: null, + in_reply_to_status_id_str: null, + in_reply_to_user_id: null, + in_reply_to_user_id_str: null, + in_reply_to_screen_name: null, + user: user, + geo: null, + coordinates: null, + place: null, + contributors: null, + is_quote_status: false, + retweet_count: 1, + favorite_count: 1, + favorited: false, + retweeted: false, + possibly_sensitive: false, + possibly_sensitive_appealable: false, + lang: "en" + } +} diff --git a/src/services/twitter/intercepts/generator/models/user.js b/src/services/twitter/intercepts/generator/models/user.js new file mode 100644 index 00000000..3d26de1a --- /dev/null +++ b/src/services/twitter/intercepts/generator/models/user.js @@ -0,0 +1,58 @@ +const { faker } = require('@faker-js/faker'); +const { getRandomInt, getDateString } = require("../util"); + +module.exports = function(screenName) { + const id = getRandomInt() + return { + "id": id, + "id_str": `${id}`, + "name": faker.person.fullName(), + "screen_name": screenName, + "location": faker.location.country() + ", " + faker.location.city(), + "description": faker.person.jobDescriptor(), + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": getDateString(), + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + } +} diff --git a/src/services/twitter/intercepts/generator/util.js b/src/services/twitter/intercepts/generator/util.js new file mode 100644 index 00000000..4a5e8a76 --- /dev/null +++ b/src/services/twitter/intercepts/generator/util.js @@ -0,0 +1,26 @@ + +function getRandomInt() { + return Math.ceil(Math.random() * 1_000_000) +} + +function getDateString() { + const date = new Date(); + + const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + + const dayOfWeek = daysOfWeek[date.getUTCDay()]; + const month = months[date.getUTCMonth()]; + const day = date.getUTCDate(); + const hours = date.getUTCHours(); + const minutes = date.getUTCMinutes(); + const seconds = date.getUTCSeconds(); + const year = date.getUTCFullYear(); + + return `${dayOfWeek} ${month} ${day} ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')} +0000 ${year}`; +} + +module.exports = { + getRandomInt, + getDateString +} diff --git a/src/services/twitter/intercepts/index.js b/src/services/twitter/intercepts/index.js index 91a9f883..ea7d289b 100644 --- a/src/services/twitter/intercepts/index.js +++ b/src/services/twitter/intercepts/index.js @@ -1,686 +1,8 @@ const nock = require('nock'); const url = require('url'); const debug = require('debug'); - const log = debug('twitter:intercept'); -function createUser(screenName) { - return { - id: 2533316504, - id_str: '2533316504', - name: 'random name', - screen_name: screenName, - location: 'Vancouver, British Columbia', - description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', - url: null, - entities: { - description: { - urls: [], - }, - }, - protected: false, - followers_count: 105, - friends_count: 157, - listed_count: 3, - created_at: 'Thu May 29 20:07:42 +0000 2014', - favourites_count: 59, - utc_offset: null, - time_zone: null, - geo_enabled: true, - verified: false, - statuses_count: 146, - lang: null, - status: { - created_at: 'Tue Feb 07 00:32:46 +0000 2023', - id: 1622755209964568576, - id_str: '1622755209964568576', - text: '@mikeal @nodejs Would love to go. Nostalgic vibes with similar outdoor activities :)', - truncated: false, - entities: { - hashtags: [], - symbols: [], - user_mentions: [ - { - screen_name: 'mikeal', - name: 'Mikeal Rogers', - id: 668423, - id_str: '668423', - indices: [ - 0, - 7, - ], - }, - { - screen_name: 'nodejs', - name: 'Node.js', - id: 91985735, - id_str: '91985735', - indices: [ - 8, - 15, - ], - }, - ], - urls: [], - }, - source: 'Twitter for iPhone', - in_reply_to_status_id: 1622624107270664192, - in_reply_to_status_id_str: '1622624107270664192', - in_reply_to_user_id: 668423, - in_reply_to_user_id_str: '668423', - in_reply_to_screen_name: 'mikeal', - geo: null, - coordinates: null, - place: null, - contributors: null, - is_quote_status: false, - retweet_count: 0, - favorite_count: 2, - favorited: false, - retweeted: false, - lang: 'en', - }, - contributors_enabled: false, - is_translator: false, - is_translation_enabled: false, - profile_background_color: 'C0DEED', - profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_tile: false, - profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', - profile_link_color: '000000', - profile_sidebar_border_color: 'C0DEED', - profile_sidebar_fill_color: 'DDEEF6', - profile_text_color: '333333', - profile_use_background_image: true, - has_extended_profile: false, - default_profile: false, - default_profile_image: false, - following: false, - follow_request_sent: false, - notifications: false, - translator_type: 'none', - withheld_in_countries: [], - suspended: false, - needs_phone_verification: false, - }; -} - -function createTwitStatusObjectMock( - screenName, - options = { reply: false } -) { - return { - created_at: 'Wed Oct 10 20:19:24 +0000 2018', - id: 1050118621198921728, - id_str: '1050118621198921728', - text: 'To make room for more expression, we will now count all ' - + 'emojis as equal—including those with gender‍‍‍ and skin t… https://t.co/MkGjXf9aXm', - truncated: true, - entities: { - hashtags: [], - symbols: [], - user_mentions: [], - urls: [ - { - url: 'https://t.co/MkGjXf9aXm', - expanded_url: 'https://twitter.com/i/web/status/1050118621198921728', - display_url: 'twitter.com/i/web/status/1…', - indices: [ - 117, - 140, - ], - }, - ], - }, - source: 'Twitter Web Client', - user: { - id: 1, - id_str: '1', - name: 'Twitter API', - screen_name: screenName, - location: 'San Francisco, CA', - description: 'The Real Twitter API. Tweets about API changes, service issues and ' - + "our Developer Platform. Don't get an answer? It's on my website.", - url: 'https://t.co/8IkCzCDr19', - entities: { - url: { - urls: [ - { - url: 'https://t.co/8IkCzCDr19', - expanded_url: 'https://developer.twitter.com', - display_url: 'developer.twitter.com', - indices: [ - 0, - 23, - ], - }, - ], - }, - description: { - urls: [], - }, - }, - protected: false, - followers_count: 6128663, - friends_count: 12, - listed_count: 12900, - created_at: 'Wed May 23 06:01:13 +0000 2007', - favourites_count: 32, - utc_offset: null, - time_zone: null, - geo_enabled: null, - verified: true, - statuses_count: 3659, - lang: 'null', - contributors_enabled: null, - is_translator: null, - is_translation_enabled: null, - profile_background_color: 'null', - profile_background_image_url: 'null', - profile_background_image_url_https: 'null', - profile_background_tile: null, - profile_image_url: 'null', - profile_image_url_https: 'https://pbs.twimg.com/profile_images/942858479592554497/BbazLO9L_normal.jpg', - profile_banner_url: 'https://pbs.twimg.com/profile_banners/6253282/1497491515', - profile_link_color: 'null', - profile_sidebar_border_color: 'null', - profile_sidebar_fill_color: 'null', - profile_text_color: 'null', - profile_use_background_image: null, - has_extended_profile: null, - default_profile: false, - default_profile_image: false, - following: null, - follow_request_sent: null, - notifications: null, - translator_type: 'null', - }, - geo: null, - coordinates: null, - place: null, - contributors: null, - is_quote_status: false, - retweet_count: 161, - favorite_count: 296, - favorited: false, - retweeted: false, - possibly_sensitive: false, - possibly_sensitive_appealable: false, - lang: 'en', - ...options.reply ? { - in_reply_to_status_id: null, - in_reply_to_status_id_str: null, - in_reply_to_user_id: 1, - in_reply_to_user_id_str: null, - in_reply_to_screen_name: null, - } : {}, - }; -} - -function createReply() { - return { - created_at: 'Sat Oct 15 17:50:29 +0000 2016', - // eslint-disable-next-line no-loss-of-precision - id: 787349945225515008, - id_str: '787349945225515008', - text: '@NodeConfEU team @MakeOmatic is in Dublin. Heading to get some dinner soon, any1 who wants to join is very welcome :)', - truncated: false, - entities: { - hashtags: [], - symbols: [], - user_mentions: [ - { - screen_name: 'NodeConfEU', - name: 'NodeConf EU Nov 6th-8th 2023', - id: 526867353, - id_str: '526867353', - indices: [ - 0, - 11, - ], - }, - { - screen_name: 'MakeOmatic', - name: 'makeomatic', - id: 1960663927, - id_str: '1960663927', - indices: [ - 17, - 28, - ], - }, - ], - urls: [], - }, - source: 'Twitter Web Client', - // eslint-disable-next-line no-loss-of-precision - in_reply_to_status_id: 1621960453323735041, - in_reply_to_status_id_str: '1621960453323735041', - in_reply_to_user_id: 356087317, - in_reply_to_user_id_str: '356087317', - in_reply_to_screen_name: 's_gimeno', - user: { - id: 2533316504, - id_str: '2533316504', - name: 'Vitaly Aminev @ Vancouver 🇨🇦', - screen_name: 'v_aminev', - location: 'Vancouver, British Columbia', - description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', - url: null, - entities: { - description: { - urls: [], - }, - }, - protected: false, - followers_count: 105, - friends_count: 157, - listed_count: 3, - created_at: 'Thu May 29 20:07:42 +0000 2014', - favourites_count: 59, - utc_offset: null, - time_zone: null, - geo_enabled: true, - verified: false, - statuses_count: 146, - lang: null, - contributors_enabled: false, - is_translator: false, - is_translation_enabled: false, - profile_background_color: 'C0DEED', - profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_tile: false, - profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', - profile_link_color: '000000', - profile_sidebar_border_color: 'C0DEED', - profile_sidebar_fill_color: 'DDEEF6', - profile_text_color: '333333', - profile_use_background_image: true, - has_extended_profile: false, - default_profile: false, - default_profile_image: false, - following: false, - follow_request_sent: false, - notifications: false, - translator_type: 'none', - withheld_in_countries: [], - }, - geo: null, - coordinates: null, - place: null, - contributors: null, - is_quote_status: false, - retweet_count: 1, - favorite_count: 1, - favorited: false, - retweeted: false, - lang: 'en', - }; -} - -function createOriginal() { - return { - created_at: 'Sat Oct 15 17:50:29 +0000 2016', - // eslint-disable-next-line no-loss-of-precision - id: 787349945225515001, - id_str: '787349945225515001', - text: '@NodeConfEU team @MakeOmatic is in Dublin. Heading to get some dinner soon, any1 who wants to join is very welcome :)', - truncated: false, - entities: { - hashtags: [], - symbols: [], - user_mentions: [ - { - screen_name: 'NodeConfEU', - name: 'NodeConf EU Nov 6th-8th 2023', - id: 526867353, - id_str: '526867353', - indices: [ - 0, - 11, - ], - }, - { - screen_name: 'MakeOmatic', - name: 'makeomatic', - id: 1960663927, - id_str: '1960663927', - indices: [ - 17, - 28, - ], - }, - ], - urls: [], - }, - source: 'Twitter Web Client', - // "in_reply_to_status_id": null, - // "in_reply_to_status_id_str": null, - // "in_reply_to_user_id": null, - // "in_reply_to_user_id_str": null, - // "in_reply_to_screen_name": null, - user: { - id: 2533316504, - id_str: '2533316504', - name: 'Vitaly Aminev @ Vancouver 🇨🇦', - screen_name: 'v_aminev', - location: 'Vancouver, British Columbia', - description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', - url: null, - entities: { - description: { - urls: [], - }, - }, - protected: false, - followers_count: 105, - friends_count: 157, - listed_count: 3, - created_at: 'Thu May 29 20:07:42 +0000 2014', - favourites_count: 59, - utc_offset: null, - time_zone: null, - geo_enabled: true, - verified: false, - statuses_count: 146, - lang: null, - contributors_enabled: false, - is_translator: false, - is_translation_enabled: false, - profile_background_color: 'C0DEED', - profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_tile: false, - profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', - profile_link_color: '000000', - profile_sidebar_border_color: 'C0DEED', - profile_sidebar_fill_color: 'DDEEF6', - profile_text_color: '333333', - profile_use_background_image: true, - has_extended_profile: false, - default_profile: false, - default_profile_image: false, - following: false, - follow_request_sent: false, - notifications: false, - translator_type: 'none', - withheld_in_countries: [], - }, - geo: null, - coordinates: null, - place: null, - contributors: null, - is_quote_status: false, - retweet_count: 1, - favorite_count: 1, - favorited: false, - retweeted: false, - lang: 'en', - }; -} - -function createRetweet() { - return { - created_at: 'Tue Jan 31 22:17:00 +0000 2023', - // eslint-disable-next-line no-loss-of-precision - id: 1620546716373254144, - id_str: '1620546716373254144', - text: 'RT @amineva_art: •Making mixed #media #artwork by playing around with its background. Fisrt #NFT ' - + 'collection drops soon•\n#digitalart #nftcol…', - truncated: false, - entities: { - hashtags: [ - { - text: 'media', - indices: [ - 31, - 37, - ], - }, - { - text: 'artwork', - indices: [ - 38, - 46, - ], - }, - { - text: 'NFT', - indices: [ - 92, - 96, - ], - }, - { - text: 'digitalart', - indices: [ - 120, - 131, - ], - }, - ], - symbols: [], - user_mentions: [ - { - screen_name: 'amineva_art', - name: 'Anya', - id: 271456488, - id_str: '271456488', - indices: [ - 3, - 15, - ], - }, - ], - urls: [], - }, - source: 'Twitter for iPhone', - in_reply_to_status_id: null, - in_reply_to_status_id_str: null, - in_reply_to_user_id: null, - in_reply_to_user_id_str: null, - in_reply_to_screen_name: null, - user: { - id: 2533316504, - id_str: '2533316504', - name: 'Vitaly Aminev @ Vancouver 🇨🇦', - screen_name: 'v_aminev', - location: 'Vancouver, British Columbia', - description: 'CTO at @streamlayer, Founder @Makeomatic Software Architect. Speaker', - url: null, - entities: { - description: { - urls: [], - }, - }, - protected: false, - followers_count: 105, - friends_count: 157, - listed_count: 3, - created_at: 'Thu May 29 20:07:42 +0000 2014', - favourites_count: 59, - utc_offset: null, - time_zone: null, - geo_enabled: true, - verified: false, - statuses_count: 146, - lang: null, - contributors_enabled: false, - is_translator: false, - is_translation_enabled: false, - profile_background_color: 'C0DEED', - profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_tile: false, - profile_image_url: 'http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_image_url_https: 'https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg', - profile_banner_url: 'https://pbs.twimg.com/profile_banners/2533316504/1404549458', - profile_link_color: '000000', - profile_sidebar_border_color: 'C0DEED', - profile_sidebar_fill_color: 'DDEEF6', - profile_text_color: '333333', - profile_use_background_image: true, - has_extended_profile: false, - default_profile: false, - default_profile_image: false, - following: false, - follow_request_sent: false, - notifications: false, - translator_type: 'none', - withheld_in_countries: [], - }, - geo: null, - coordinates: null, - place: null, - contributors: null, - retweeted_status: { - created_at: 'Fri Jan 27 02:00:01 +0000 2023', - // eslint-disable-next-line no-loss-of-precision - id: 1618790903912480768, - id_str: '1618790903912480768', - text: '•Making mixed #media #artwork by playing around with its background. ' - + 'Fisrt #NFT collection drops soon•\n#digitalart… https://t.co/te1xkATUVG', - truncated: true, - entities: { - hashtags: [ - { - text: 'media', - indices: [ - 14, - 20, - ], - }, - { - text: 'artwork', - indices: [ - 21, - 29, - ], - }, - { - text: 'NFT', - indices: [ - 75, - 79, - ], - }, - { - text: 'digitalart', - indices: [ - 103, - 114, - ], - }, - ], - symbols: [], - user_mentions: [], - urls: [ - { - url: 'https://t.co/te1xkATUVG', - expanded_url: 'https://twitter.com/i/web/status/1618790903912480768', - display_url: 'twitter.com/i/web/status/1…', - indices: [ - 116, - 139, - ], - }, - ], - }, - source: 'FeedHive', - in_reply_to_status_id: null, - in_reply_to_status_id_str: null, - in_reply_to_user_id: null, - in_reply_to_user_id_str: null, - in_reply_to_screen_name: null, - user: { - id: 271456488, - id_str: '271456488', - name: 'Anya', - screen_name: 'amineva_art', - location: 'Vancouver', - description: 'NFT artist / Illustrator / Painter / Animator. In love with digital creatures. ' - + 'Design Evangelist / Founder at https://t.co/GtOcuhBqNf 🇨🇦 Instagram: @amineva_art', - url: null, - entities: { - description: { - urls: [ - { - url: 'https://t.co/GtOcuhBqNf', - expanded_url: 'http://Makeomatic.ca', - display_url: 'Makeomatic.ca', - indices: [ - 110, - 133, - ], - }, - ], - }, - }, - protected: false, - followers_count: 94, - friends_count: 88, - listed_count: 3, - created_at: 'Thu Mar 24 15:00:47 +0000 2011', - favourites_count: 55, - utc_offset: null, - time_zone: null, - geo_enabled: true, - verified: false, - statuses_count: 549, - lang: null, - contributors_enabled: false, - is_translator: false, - is_translation_enabled: false, - profile_background_color: '0A0A0A', - profile_background_image_url: 'http://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_image_url_https: 'https://abs.twimg.com/images/themes/theme1/bg.png', - profile_background_tile: true, - profile_image_url: 'http://pbs.twimg.com/profile_images/1577656071539363845/9cBL_BeW_normal.jpg', - profile_image_url_https: 'https://pbs.twimg.com/profile_images/1577656071539363845/9cBL_BeW_normal.jpg', - profile_banner_url: 'https://pbs.twimg.com/profile_banners/271456488/1541105104', - profile_link_color: '2B59B5', - profile_sidebar_border_color: 'FFFFFF', - profile_sidebar_fill_color: 'EADEAA', - profile_text_color: '333333', - profile_use_background_image: true, - has_extended_profile: false, - default_profile: false, - default_profile_image: false, - following: true, - follow_request_sent: false, - notifications: false, - translator_type: 'none', - withheld_in_countries: [], - }, - geo: null, - coordinates: null, - place: null, - contributors: null, - is_quote_status: false, - retweet_count: 1, - favorite_count: 9, - favorited: true, - retweeted: true, - possibly_sensitive: false, - lang: 'en', - }, - is_quote_status: false, - retweet_count: 1, - favorite_count: 0, - favorited: true, - retweeted: true, - lang: 'en', - }; -} - function interceptTwitterApi() { log('using twitter api interceptor'); nock.disableNetConnect() @@ -696,7 +18,9 @@ function interceptTwitterApi() { log(`Intercepted GET request to: ${uri}`); log('Request body: ', requestBody); log(`query:${JSON.stringify(q.query)}`); - return [200, [createUser(q.query.screen_name)]]; + return [200, [ + require(`./data/${q.query.screen_name}/user.json`) + ]]; }); nock('https://api.twitter.com') @@ -712,9 +36,9 @@ function interceptTwitterApi() { log('Request body: ', requestBody); log(`query:${JSON.stringify(q.query)}`); const response = [ - createOriginal(), - createReply(), - createRetweet(), + require(`./data/${q.query.screen_name}/original.json`), + require(`./data/${q.query.screen_name}/reply.json`), + require(`./data/${q.query.screen_name}/retweet.json`), ]; return [200, response]; }); @@ -726,15 +50,21 @@ function interceptTwitterApi() { return uri.includes('statuses/show'); }) .reply(function (uri, requestBody) { - log('checkin statuses/show'); const q = url.parse(uri, true); + + log('checkin statuses/show'); log(`Intercepted GET request to: ${uri}`); log('Request body: ', requestBody); log(`query:${JSON.stringify(q.query)}`); - return [200, createTwitStatusObjectMock('v_aminev')]; + + const filename = q.pathname.split("/").pop() + const screenName = "v_aminev" + const tweets = require(`./data/${screenName}/tweets.json`) + + return [200, require(`./data/${screenName}/${tweets[filename]}`)]; }); } module.exports = { - interceptTwitterApi, -}; + interceptTwitterApi +} diff --git a/src/social.js b/src/social.js index 5dd7ce1e..f690af46 100755 --- a/src/social.js +++ b/src/social.js @@ -15,7 +15,7 @@ const { interceptTwitterApi } = require('./services/twitter/intercepts'); const services = new WeakMap(); -if (process.env.TEST_MODE) { +if (process.env.INTERCEPT_TWITTER_API) { interceptTwitterApi(); } diff --git a/test/docker-compose.yml b/test/docker-compose.yml index ae6ba18b..2356dc94 100755 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -28,4 +28,4 @@ services: NODE_ENV: "test" DEBUG: ${DEBUG} NCONF_NAMESPACE: MS_SOCIAL - TEST_MODE: ${TEST_MODE} + INTERCEPT_TWITTER_API: ${INTERCEPT_TWITTER_API} From cddbb8a2b4e6fb4624fa98596bd3e326dc465525 Mon Sep 17 00:00:00 2001 From: ildar Date: Fri, 26 May 2023 06:25:10 +0600 Subject: [PATCH 4/8] fix: major update with statuses/filter and so on --- .../data/evgenypoyarkov/tweets.json | 9 +- .../twitter/intercepts/data/jack/status.json | 102 +++++ .../twitter/intercepts/data/reid/status.json | 418 ++++++++++++++++++ .../intercepts/data/v_aminev/reply.json | 4 +- .../intercepts/data/v_aminev/tweets.json | 8 +- .../twitter/intercepts/generator/cli.js | 8 +- .../twitter/intercepts/generator/factories.js | 4 +- .../intercepts/generator/models/original.js | 4 +- src/services/twitter/intercepts/index.js | 181 ++++++-- test/suites/01.twitter.js | 7 + test/suites/twitter.filter.js | 4 +- 11 files changed, 685 insertions(+), 64 deletions(-) create mode 100644 src/services/twitter/intercepts/data/jack/status.json create mode 100644 src/services/twitter/intercepts/data/reid/status.json diff --git a/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json b/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json index ced32226..f7990767 100644 --- a/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json +++ b/src/services/twitter/intercepts/data/evgenypoyarkov/tweets.json @@ -1,5 +1,6 @@ { - "146595.json": "original.json", - "97762.json": "retweet.json", - "231653.json": "reply.json" -} \ No newline at end of file + "146595": "original.json", + "97762": "retweet.json", + "231653": "reply.json", + "20": "original-20.json" +} diff --git a/src/services/twitter/intercepts/data/jack/status.json b/src/services/twitter/intercepts/data/jack/status.json new file mode 100644 index 00000000..4003c932 --- /dev/null +++ b/src/services/twitter/intercepts/data/jack/status.json @@ -0,0 +1,102 @@ +{ + "created_at": "Thu May 25 10:38:58 +0000 2023", + "id": 20, + "id_str": "20", + "text": "just setting up my twttr", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 0, + 11 + ] + }, + { + "screen_name": "MakeOmatic", + "name": "makeomatic", + "id": 1960663927, + "id_str": "1960663927", + "indices": [ + 17, + 28 + ] + } + ], + "urls": [] + }, + "source": "Twitter Web Client", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 12, + "id_str": "12", + "name": "Bill Crooks", + "screen_name": "jack", + "location": "French Guiana, Michealport", + "description": "Regional", + "url": null, + "entities": { + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 105, + "friends_count": 157, + "listed_count": 3, + "created_at": "Thu May 25 10:38:58 +0000 2023", + "favourites_count": 59, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": true, + "statuses_count": 146, + "lang": null, + "status": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "C0DEED", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1540076330191974400/hwpwsAJg_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2533316504/1404549458", + "profile_link_color": "000000", + "profile_sidebar_border_color": "C0DEED", + "profile_sidebar_fill_color": "DDEEF6", + "profile_text_color": "333333", + "profile_use_background_image": true, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [], + "suspended": false, + "needs_phone_verification": false + }, + "geo": null, + "coordinates": null, + "place": null, + "contributors": null, + "is_quote_status": false, + "retweet_count": 1, + "favorite_count": 1, + "favorited": false, + "retweeted": false, + "lang": "en" +} diff --git a/src/services/twitter/intercepts/data/reid/status.json b/src/services/twitter/intercepts/data/reid/status.json new file mode 100644 index 00000000..5363edde --- /dev/null +++ b/src/services/twitter/intercepts/data/reid/status.json @@ -0,0 +1,418 @@ +{ + "created_at": "Mon Oct 17 19:27:50 +0000 2016", + "id": 788099220381335552, + "id_str": "788099220381335552", + "text": "Celtic drummers outside Kilkenny Castle were amazing! Thanks @NodeConfEU for the fine hospitality. https://t.co/niCaEinjjd", + "truncated": false, + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [ + { + "screen_name": "NodeConfEU", + "name": "NodeConf EU Nov 6th-8th 2023", + "id": 526867353, + "id_str": "526867353", + "indices": [ + 61, + 72 + ] + } + ], + "urls": [ + { + "url": "https://t.co/niCaEinjjd", + "expanded_url": "https://twitter.com/NodeConfEU/status/788098182714720256", + "display_url": "twitter.com/NodeConfEU/sta…", + "indices": [ + 100, + 123 + ] + } + ] + }, + "source": "Tweetbot for iΟS", + "in_reply_to_status_id": 788098182714720256, + "in_reply_to_status_id_str": "788098182714720256", + "in_reply_to_user_id": 526867353, + "in_reply_to_user_id_str": "526867353", + "in_reply_to_screen_name": "NodeConfEU", + "user": { + "id": 2187, + "id_str": "2187", + "name": "Reid Burke", + "screen_name": "reid", + "location": "San Jose, California", + "description": "Loving people, building things. Husband to @jeeyunit. Also found over here: @reid@intentional.network", + "url": "https://t.co/EC648mfifU", + "entities": { + "url": { + "urls": [ + { + "url": "https://t.co/EC648mfifU", + "expanded_url": "https://reidburke.com", + "display_url": "reidburke.com", + "indices": [ + 0, + 23 + ] + } + ] + }, + "description": { + "urls": [] + } + }, + "protected": false, + "followers_count": 1578, + "friends_count": 363, + "listed_count": 102, + "created_at": "Tue Jul 18 04:45:15 +0000 2006", + "favourites_count": 2353, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 4286, + "lang": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "F2F2F2", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme15/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme15/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1369300745510658049/D3-hpDIN_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1369300745510658049/D3-hpDIN_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/2187/1615301593", + "profile_link_color": "1B95E0", + "profile_sidebar_border_color": "FFFFFF", + "profile_sidebar_fill_color": "E6FFD1", + "profile_text_color": "2D2E40", + "profile_use_background_image": false, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": false, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [] + }, + "geo": null, + "coordinates": null, + "place": { + "id": "83e9c5185856cabc", + "url": "https://api.twitter.com/1.1/geo/id/83e9c5185856cabc.json", + "place_type": "city", + "name": "Kilkenny", + "full_name": "Kilkenny, Ireland", + "country_code": "IE", + "country": "Ireland", + "contained_within": [], + "bounding_box": { + "type": "Polygon", + "coordinates": [ + [ + [ + -7.6733888, + 52.2425457 + ], + [ + -6.9142322, + 52.2425457 + ], + [ + -6.9142322, + 52.8944269 + ], + [ + -7.6733888, + 52.8944269 + ] + ] + ] + }, + "attributes": {} + }, + "contributors": null, + "is_quote_status": true, + "quoted_status_id": 788098182714720256, + "quoted_status_id_str": "788098182714720256", + "quoted_status": { + "created_at": "Mon Oct 17 19:23:43 +0000 2016", + "id": 788098182714720256, + "id_str": "788098182714720256", + "text": "Celtic drummers on arrival! #NodeConfEU #Kilkenny https://t.co/8loCawojWv", + "truncated": false, + "entities": { + "hashtags": [ + { + "text": "NodeConfEU", + "indices": [ + 28, + 39 + ] + }, + { + "text": "Kilkenny", + "indices": [ + 40, + 49 + ] + } + ], + "symbols": [], + "user_mentions": [], + "urls": [], + "media": [ + { + "id": 788097978926034944, + "id_str": "788097978926034944", + "indices": [ + 50, + 73 + ], + "media_url": "http://pbs.twimg.com/ext_tw_video_thumb/788097978926034944/pu/img/l5dSXoCJoVTism03.jpg", + "media_url_https": "https://pbs.twimg.com/ext_tw_video_thumb/788097978926034944/pu/img/l5dSXoCJoVTism03.jpg", + "url": "https://t.co/8loCawojWv", + "display_url": "pic.twitter.com/8loCawojWv", + "expanded_url": "https://twitter.com/NodeConfEU/status/788098182714720256/video/1", + "type": "photo", + "sizes": { + "thumb": { + "w": 150, + "h": 150, + "resize": "crop" + }, + "small": { + "w": 383, + "h": 680, + "resize": "fit" + }, + "large": { + "w": 720, + "h": 1280, + "resize": "fit" + }, + "medium": { + "w": 675, + "h": 1200, + "resize": "fit" + } + } + } + ] + }, + "extended_entities": { + "media": [ + { + "id": 788097978926034944, + "id_str": "788097978926034944", + "indices": [ + 50, + 73 + ], + "media_url": "http://pbs.twimg.com/ext_tw_video_thumb/788097978926034944/pu/img/l5dSXoCJoVTism03.jpg", + "media_url_https": "https://pbs.twimg.com/ext_tw_video_thumb/788097978926034944/pu/img/l5dSXoCJoVTism03.jpg", + "url": "https://t.co/8loCawojWv", + "display_url": "pic.twitter.com/8loCawojWv", + "expanded_url": "https://twitter.com/NodeConfEU/status/788098182714720256/video/1", + "type": "video", + "sizes": { + "thumb": { + "w": 150, + "h": 150, + "resize": "crop" + }, + "small": { + "w": 383, + "h": 680, + "resize": "fit" + }, + "large": { + "w": 720, + "h": 1280, + "resize": "fit" + }, + "medium": { + "w": 675, + "h": 1200, + "resize": "fit" + } + }, + "video_info": { + "aspect_ratio": [ + 9, + 16 + ], + "duration_millis": 16137, + "variants": [ + { + "bitrate": 832000, + "content_type": "video/mp4", + "url": "https://video.twimg.com/ext_tw_video/788097978926034944/pu/vid/360x640/Z-0TBWQTDp5BhUGw.mp4" + }, + { + "bitrate": 2176000, + "content_type": "video/mp4", + "url": "https://video.twimg.com/ext_tw_video/788097978926034944/pu/vid/720x1280/z0CWe4W3kWSEMwgV.mp4" + }, + { + "content_type": "application/x-mpegURL", + "url": "https://video.twimg.com/ext_tw_video/788097978926034944/pu/pl/Oh8yHoHj8R5aHdDY.m3u8" + }, + { + "bitrate": 320000, + "content_type": "video/mp4", + "url": "https://video.twimg.com/ext_tw_video/788097978926034944/pu/vid/180x320/M9I157TlEOS3DclN.mp4" + } + ] + }, + "additional_media_info": { + "monetizable": false + } + } + ] + }, + "source": "Twitter for Android", + "in_reply_to_status_id": null, + "in_reply_to_status_id_str": null, + "in_reply_to_user_id": null, + "in_reply_to_user_id_str": null, + "in_reply_to_screen_name": null, + "user": { + "id": 526867353, + "id_str": "526867353", + "name": "NodeConf EU Nov 6th-8th 2023", + "screen_name": "NodeConfEU", + "location": "", + "description": "Nov 6th-8th 2023 at @lyrathestate | 📹 Watch back 2022: https://t.co/3bX7iwoWwS | 📸 https://t.co/l0NI9JopvW | Organised by @NearForm", + "url": "https://t.co/mfsBek3Idf", + "entities": { + "url": { + "urls": [ + { + "url": "https://t.co/mfsBek3Idf", + "expanded_url": "http://www.nodeconf.eu", + "display_url": "nodeconf.eu", + "indices": [ + 0, + 23 + ] + } + ] + }, + "description": { + "urls": [ + { + "url": "https://t.co/3bX7iwoWwS", + "expanded_url": "http://nf.ie/NCEU22", + "display_url": "nf.ie/NCEU22", + "indices": [ + 55, + 78 + ] + }, + { + "url": "https://t.co/l0NI9JopvW", + "expanded_url": "http://nf.ie/NCEU22pics", + "display_url": "nf.ie/NCEU22pics", + "indices": [ + 83, + 106 + ] + } + ] + } + }, + "protected": false, + "followers_count": 5099, + "friends_count": 1754, + "listed_count": 213, + "created_at": "Fri Mar 16 22:45:48 +0000 2012", + "favourites_count": 1814, + "utc_offset": null, + "time_zone": null, + "geo_enabled": true, + "verified": false, + "statuses_count": 4297, + "lang": null, + "contributors_enabled": false, + "is_translator": false, + "is_translation_enabled": false, + "profile_background_color": "000000", + "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", + "profile_background_tile": false, + "profile_image_url": "http://pbs.twimg.com/profile_images/1641024326139879425/wEE4x5oa_normal.jpg", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1641024326139879425/wEE4x5oa_normal.jpg", + "profile_banner_url": "https://pbs.twimg.com/profile_banners/526867353/1680084544", + "profile_link_color": "B12C65", + "profile_sidebar_border_color": "000000", + "profile_sidebar_fill_color": "000000", + "profile_text_color": "000000", + "profile_use_background_image": false, + "has_extended_profile": false, + "default_profile": false, + "default_profile_image": false, + "following": true, + "follow_request_sent": false, + "notifications": false, + "translator_type": "none", + "withheld_in_countries": [] + }, + "geo": null, + "coordinates": null, + "place": { + "id": "83e9c5185856cabc", + "url": "https://api.twitter.com/1.1/geo/id/83e9c5185856cabc.json", + "place_type": "city", + "name": "Kilkenny", + "full_name": "Kilkenny, Ireland", + "country_code": "IE", + "country": "Ireland", + "contained_within": [], + "bounding_box": { + "type": "Polygon", + "coordinates": [ + [ + [ + -7.6733888, + 52.2425457 + ], + [ + -6.9142322, + 52.2425457 + ], + [ + -6.9142322, + 52.8944269 + ], + [ + -7.6733888, + 52.8944269 + ] + ] + ] + }, + "attributes": {} + }, + "contributors": null, + "is_quote_status": false, + "retweet_count": 2, + "favorite_count": 6, + "favorited": false, + "retweeted": false, + "possibly_sensitive": false, + "possibly_sensitive_appealable": false, + "lang": "en" + }, + "retweet_count": 3, + "favorite_count": 3, + "favorited": false, + "retweeted": true, + "possibly_sensitive": false, + "possibly_sensitive_appealable": false, + "lang": "en" +} diff --git a/src/services/twitter/intercepts/data/v_aminev/reply.json b/src/services/twitter/intercepts/data/v_aminev/reply.json index 011ac91a..6929ba23 100644 --- a/src/services/twitter/intercepts/data/v_aminev/reply.json +++ b/src/services/twitter/intercepts/data/v_aminev/reply.json @@ -2,7 +2,7 @@ "created_at": "Thu May 25 10:32:11 +0000 2023", "id": 991460, "id_str": "991460", - "text": "Atque libero sunt iure doloremque qui eveniet officia delectus perferendis.", + "text": "Atque libero sunt iure doloremque qui eveniet officia delectus perferendis. Atque libero sunt iure doloremque qui eveniet officia delectus perferendis. Atque libero sunt iure doloremque qui eveniet officia delectus perfe", "truncated": false, "entities": { "hashtags": [], @@ -99,4 +99,4 @@ "favorited": false, "retweeted": false, "lang": "en" -} \ No newline at end of file +} diff --git a/src/services/twitter/intercepts/data/v_aminev/tweets.json b/src/services/twitter/intercepts/data/v_aminev/tweets.json index 1785e11a..8a98b2e7 100644 --- a/src/services/twitter/intercepts/data/v_aminev/tweets.json +++ b/src/services/twitter/intercepts/data/v_aminev/tweets.json @@ -1,5 +1,5 @@ { - "904549.json": "original.json", - "772961.json": "retweet.json", - "991460.json": "reply.json" -} \ No newline at end of file + "904549": "original.json", + "772961": "retweet.json", + "991460": "reply.json" +} diff --git a/src/services/twitter/intercepts/generator/cli.js b/src/services/twitter/intercepts/generator/cli.js index 254ab572..f55828b7 100644 --- a/src/services/twitter/intercepts/generator/cli.js +++ b/src/services/twitter/intercepts/generator/cli.js @@ -1,16 +1,16 @@ const fs = require("fs"); const { userFactory, originalFactory, replyFactory, retweetFactory } = require("./factories"); -const screenName = "evgenypoyarkov" +const screenName = "v_aminev" const user = userFactory(screenName) const retweet = retweetFactory(user) const original = originalFactory(user) const reply = replyFactory(user) const tweets = {} -tweets[`${original.id}.json`] = "original.json" -tweets[`${retweet.id}.json`] = "retweet.json" -tweets[`${reply.id}.json`] = "reply.json" +tweets[`${original.id}`] = "original.json" +tweets[`${retweet.id}`] = "retweet.json" +tweets[`${reply.id}`] = "reply.json" console.log(user) console.log(original) diff --git a/src/services/twitter/intercepts/generator/factories.js b/src/services/twitter/intercepts/generator/factories.js index ef7fd2ea..aed6a443 100644 --- a/src/services/twitter/intercepts/generator/factories.js +++ b/src/services/twitter/intercepts/generator/factories.js @@ -21,9 +21,9 @@ function replyFactory(user) { return createReply(user, mentions, tweet) } -function originalFactory(user) { +function originalFactory(user, options) { const mentions = createMentions() - return createOriginal(user, mentions) + return createOriginal(user, mentions, options) } function statusFactory(user) { diff --git a/src/services/twitter/intercepts/generator/models/original.js b/src/services/twitter/intercepts/generator/models/original.js index 84d134f3..69b34808 100644 --- a/src/services/twitter/intercepts/generator/models/original.js +++ b/src/services/twitter/intercepts/generator/models/original.js @@ -2,8 +2,8 @@ const { getRandomInt, getDateString } = require("../util"); const { faker } = require("@faker-js/faker"); -module.exports = function(user, mentions) { - const id = getRandomInt() +module.exports = function(user, mentions, options = {}) { + const id = options.id ?? getRandomInt() return { created_at: getDateString(), // eslint-disable-next-line no-loss-of-precision diff --git a/src/services/twitter/intercepts/index.js b/src/services/twitter/intercepts/index.js index ea7d289b..dc2ab2e1 100644 --- a/src/services/twitter/intercepts/index.js +++ b/src/services/twitter/intercepts/index.js @@ -2,67 +2,160 @@ const nock = require('nock'); const url = require('url'); const debug = require('debug'); const log = debug('twitter:intercept'); +const Stream = require('stream'); +const fs = require('fs'); +const { userFactory, originalFactory, replyFactory, retweetFactory } = require("./generator/factories"); +function hasUser(name) { + return fs.existsSync(`./src/services/twitter/intercepts/data/${name}`) +} + +// message: JSON.stringify([{ code: 17, message: 'No user matches for specified terms.' }]), function interceptTwitterApi() { log('using twitter api interceptor'); - nock.disableNetConnect() - nock('https://api.twitter.com') + + const scope = nock('https://api.twitter.com', { allowUnmocked: false }) .persist() + // lookup correct user .get((uri) => { - log(`getting request for uri=${uri}`); - return uri.includes('users/lookup'); + const q = url.parse(uri, true) + const { screen_name } = q.query + const matched = uri.includes('users/lookup') && hasUser(screen_name) + if ( matched ) { + log(`getting request for existing users, for uri=${uri}, screen_name=${screen_name}`) + } + return matched }) - .reply(function (uri, requestBody) { - log('checkin users/lookup'); + .reply(200, function (uri) { const q = url.parse(uri, true); - log(`Intercepted GET request to: ${uri}`); - log('Request body: ', requestBody); - log(`query:${JSON.stringify(q.query)}`); - return [200, [ - require(`./data/${q.query.screen_name}/user.json`) - ]]; - }); - - nock('https://api.twitter.com') - .persist() + const { screen_name } = q.query + const user = require(`./data/${screen_name}/user.json`) + log(`sending response for uri=${uri}, screen_name=${screen_name}`, JSON.stringify(user)) + return [ user ] + }) + // lookup incorrect user .get((uri) => { - log(`getting request for uri=${uri}`); - return uri.includes('statuses/user_timeline'); + const q = url.parse(uri, true) + const { screen_name } = q.query + const matched = uri.includes('users/lookup') && !hasUser(screen_name) + if ( matched ) { + log(`getting request non-existing users, for uri=${uri}, screen_name=${screen_name}`) + } + return matched + }) + .reply(404, function(uri) { + const q = url.parse(uri, true) + const { screen_name } = q.query + log(`sending response for non-existing user, screen_name=${screen_name}`) + return JSON.stringify({ "errors": [{ "code": 17, "message": "No user matches for specified terms." }] }) }) - .reply(function (uri, requestBody) { - log('checkin statuses/user_timeline'); + // user timeline + .get((uri) => { + const q = url.parse(uri, true) + const { screen_name } = q.query + const matched = uri.includes('statuses/user_timeline') && hasUser(screen_name) + if ( matched ) { + log(`getting request for uri=${uri}, screen_name=${screen_name}`) + } + return matched + }) + .reply(200, function (uri) { const q = url.parse(uri, true); - log(`Intercepted GET request to: ${uri}`); - log('Request body: ', requestBody); - log(`query:${JSON.stringify(q.query)}`); + const { screen_name } = q.query const response = [ - require(`./data/${q.query.screen_name}/original.json`), - require(`./data/${q.query.screen_name}/reply.json`), - require(`./data/${q.query.screen_name}/retweet.json`), - ]; - return [200, response]; - }); - - nock('https://api.twitter.com') - .persist() + require(`./data/${screen_name}/original.json`), + require(`./data/${screen_name}/reply.json`), + require(`./data/${screen_name}/retweet.json`), + ] + log(`sending response for uri=${uri}, screen_name=${screen_name}`, JSON.stringify(response.map(item => item.id))) + return response + }) + // destroy status + .post((uri) => { + const matched = uri.includes('statuses/destroy') + if (matched) { + log(`getting request for uri=${uri}`) + } + return matched + }) + .reply(200, function (uri) { + const q = url.parse(uri, true) + const id = q.pathname.split("/").pop().replace(/\.json/, '') + const user = userFactory() + const original = originalFactory(user, { id }) + log(`sending response for statuses/destroy`, uri, JSON.stringify(original)) + return original; + }) + // statuses show .get((uri) => { - log(1, () => `getting request for uri=${uri}`); - return uri.includes('statuses/show'); + const matched = uri.includes('statuses/show') && uri.includes("id=") + if ( matched ) { + log(`getting request for uri=${uri}`); + } + return matched }) - .reply(function (uri, requestBody) { + .reply(function (uri) { + const q = url.parse(uri, true); + const id = q.query.id - log('checkin statuses/show'); - log(`Intercepted GET request to: ${uri}`); - log('Request body: ', requestBody); - log(`query:${JSON.stringify(q.query)}`); + let user, file - const filename = q.pathname.split("/").pop() - const screenName = "v_aminev" - const tweets = require(`./data/${screenName}/tweets.json`) + if ( id === "20" ) { + user = "jack" + file = "status.json" + } + else if ( id === "788099220381335552" ) { + user = "reid" + file = "status.json" + } + else { + user = 'v_aminev' + const tweets = require(`./data/${user}/tweets.json`) + file = tweets[id] + } - return [200, require(`./data/${screenName}/${tweets[filename]}`)]; - }); + if (!file) { + log(`interception error: tweet id=${id} not found`) + // actually twitter return 404 ,but tests expect 400, it is weird + return [400, JSON.stringify({ "errors": [{ "code": 144, "message": "No status found with that ID." }] })] + } else { + const response = require(`./data/${user}/${file}`) + log(`sending response to uri=${uri}, id=${id}, file=${file}, user=${user}, response=${JSON.stringify(response)}`) + return [200, response]; + } + }) + // update statuses + .post((uri) => { + const matched = uri.includes('statuses/update') + if ( matched ) { + log(`getting request for uri=${uri}`) + } + return matched + }) + .reply(200, function (uri, body) { + const response = require(`./data/v_aminev/reply.json`) + log(`sending response for statuses/update, uri=${uri}, body=${body}, response=${response.id}`) + return response; + }) + // stream statuses/filter + .post((uri) => { + const matched = uri.includes('statuses/filter') + if ( matched ) { + const q = url.parse(uri, true); + log(`getting request for POST uri=${uri}, ${JSON.stringify(q.query)}`); + } + return matched + }) + .reply(200, function (uri, body) { + log(`sending response for statuses/filter, uri=${uri}, body=${body}`) + const stream = new Stream.Duplex() + stream.on("close", () => { + log(`should interception be over?`) + // nock.restore() + }) + return stream; + }) } module.exports = { diff --git a/test/suites/01.twitter.js b/test/suites/01.twitter.js index 67843a8b..831ad158 100644 --- a/test/suites/01.twitter.js +++ b/test/suites/01.twitter.js @@ -124,6 +124,13 @@ describe('twitter', function testSuite() { after('cleanup feeds', () => service.knex('feeds').delete()); it('should return error if request to register is not valid', async () => { + // try { + // const response = service.amqp.publishAndWait(uri.register, payload.registerFail) + // console.log(response) + // } catch(err) { + // console.log(err) + // throw err + // } await assert.rejects(service.amqp.publishAndWait(uri.register, payload.registerFail), { name: 'HttpStatusError', statusCode: 400, diff --git a/test/suites/twitter.filter.js b/test/suites/twitter.filter.js index 41771657..8d0ca3c6 100644 --- a/test/suites/twitter.filter.js +++ b/test/suites/twitter.filter.js @@ -4,8 +4,8 @@ const assert = require('assert'); const filterByType = (tweets, type) => tweets.filter((x) => Number.parseInt(x.attributes.type, 10) === type); [ - [true, - /* filters */ [true, true], + [ /* ignoreFilters */ true, + /* filters */ [ /* filterReplies */ true, /* filterRetweets */ true], /* expectedTypes */ [0, 1, 2], /* filteredTypes */ [], ], From 00c7c647019812ab67f4e9fe8e0e184333d7f530 Mon Sep 17 00:00:00 2001 From: ildar Date: Fri, 26 May 2023 06:26:08 +0600 Subject: [PATCH 5/8] fix: require improved --- src/social.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/social.js b/src/social.js index f690af46..8f5815f4 100755 --- a/src/social.js +++ b/src/social.js @@ -11,11 +11,11 @@ const Facebook = require('./services/facebook'); const Notifier = require('./services/notifier'); const Instagram = require('./services/instagram'); const addUpsert = require('./utils/knex/upsert'); -const { interceptTwitterApi } = require('./services/twitter/intercepts'); const services = new WeakMap(); if (process.env.INTERCEPT_TWITTER_API) { + const { interceptTwitterApi } = require('./services/twitter/intercepts'); interceptTwitterApi(); } From c1d6ee28e4cf9ea3d1ae9e8b9603c6470c10c905 Mon Sep 17 00:00:00 2001 From: ildar Date: Fri, 26 May 2023 06:30:16 +0600 Subject: [PATCH 6/8] fix: randomstring uninstalled --- package.json | 1 - pnpm-lock.yaml | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/package.json b/package.json index 5881910c..cd9052fe 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "pg": "^8.8.0", "pino": "^7.11.0", "prom-client": "^14.1.0", - "randomstring": "^1.2.3", "request": "^2.88.2", "request-promise": "^4.2.6", "retry": "^0.13.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e01cc147..78f3169b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,7 +54,6 @@ specifiers: pg: ^8.8.0 pino: ^7.11.0 prom-client: ^14.1.0 - randomstring: ^1.2.3 request: ^2.88.2 request-promise: ^4.2.6 retry: ^0.13.1 @@ -100,7 +99,6 @@ dependencies: pg: 8.8.0 pino: 7.11.0 prom-client: 14.1.0 - randomstring: 1.2.3 request: 2.88.2 request-promise: 4.2.6_request@2.88.2 retry: 0.13.1 @@ -2372,11 +2370,6 @@ packages: engines: {node: '>=8'} dev: true - /array-uniq/1.0.2: - resolution: {integrity: sha512-GVYjmpL05al4dNlKJm53mKE4w9OOLiuVHWorsIA3YVz+Hu0hcn6PtE3Ydl0EqU7v+7ABC4mjjWsnLUxbpno+CA==} - engines: {node: '>=0.10.0'} - dev: false - /array.prototype.flat/1.2.5: resolution: {integrity: sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==} engines: {node: '>= 0.4'} @@ -6854,24 +6847,12 @@ packages: resolution: {integrity: sha512-Wswj8ZvzdI3VhaGPkZAxaCTwuMmGtgWt7Zxsgyo4P+iTmVnkojvyWaOep5q3ZjMIecW0wtQa66GWxaKkZ24RAA==} dev: true - /randombytes/2.0.3: - resolution: {integrity: sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==} - dev: false - /randombytes/2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: true - /randomstring/1.2.3: - resolution: {integrity: sha512-3dEFySepTzp2CvH6W/ASYGguPPveBuz5MpZ7MuoUkoVehmyNl9+F9c9GFVrz2QPbM9NXTIHGcmJDY/3j4677kQ==} - hasBin: true - dependencies: - array-uniq: 1.0.2 - randombytes: 2.0.3 - dev: false - /rc/1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true From 5a6baf8897fc9c331d06e0538c1f407dc6057b7a Mon Sep 17 00:00:00 2001 From: ildar Date: Fri, 26 May 2023 10:05:24 +0600 Subject: [PATCH 7/8] fix: stream mock --- src/services/twitter/intercepts/index.js | 76 +++++++++++++++--------- test/suites/01.twitter.js | 4 +- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/services/twitter/intercepts/index.js b/src/services/twitter/intercepts/index.js index dc2ab2e1..c34ee876 100644 --- a/src/services/twitter/intercepts/index.js +++ b/src/services/twitter/intercepts/index.js @@ -14,14 +14,14 @@ function hasUser(name) { function interceptTwitterApi() { log('using twitter api interceptor'); - const scope = nock('https://api.twitter.com', { allowUnmocked: false }) + nock('https://api.twitter.com', { allowUnmocked: false }) .persist() // lookup correct user .get((uri) => { const q = url.parse(uri, true) const { screen_name } = q.query const matched = uri.includes('users/lookup') && hasUser(screen_name) - if ( matched ) { + if (matched) { log(`getting request for existing users, for uri=${uri}, screen_name=${screen_name}`) } return matched @@ -31,19 +31,19 @@ function interceptTwitterApi() { const { screen_name } = q.query const user = require(`./data/${screen_name}/user.json`) log(`sending response for uri=${uri}, screen_name=${screen_name}`, JSON.stringify(user)) - return [ user ] + return [user] }) // lookup incorrect user .get((uri) => { const q = url.parse(uri, true) const { screen_name } = q.query const matched = uri.includes('users/lookup') && !hasUser(screen_name) - if ( matched ) { + if (matched) { log(`getting request non-existing users, for uri=${uri}, screen_name=${screen_name}`) } return matched }) - .reply(404, function(uri) { + .reply(404, function (uri) { const q = url.parse(uri, true) const { screen_name } = q.query log(`sending response for non-existing user, screen_name=${screen_name}`) @@ -54,7 +54,7 @@ function interceptTwitterApi() { const q = url.parse(uri, true) const { screen_name } = q.query const matched = uri.includes('statuses/user_timeline') && hasUser(screen_name) - if ( matched ) { + if (matched) { log(`getting request for uri=${uri}, screen_name=${screen_name}`) } return matched @@ -89,7 +89,7 @@ function interceptTwitterApi() { // statuses show .get((uri) => { const matched = uri.includes('statuses/show') && uri.includes("id=") - if ( matched ) { + if (matched) { log(`getting request for uri=${uri}`); } return matched @@ -101,15 +101,13 @@ function interceptTwitterApi() { let user, file - if ( id === "20" ) { + if (id === "20") { user = "jack" file = "status.json" - } - else if ( id === "788099220381335552" ) { + } else if (id === "788099220381335552") { user = "reid" file = "status.json" - } - else { + } else { user = 'v_aminev' const tweets = require(`./data/${user}/tweets.json`) file = tweets[id] @@ -128,34 +126,58 @@ function interceptTwitterApi() { // update statuses .post((uri) => { const matched = uri.includes('statuses/update') - if ( matched ) { + if (matched) { log(`getting request for uri=${uri}`) } return matched }) .reply(200, function (uri, body) { const response = require(`./data/v_aminev/reply.json`) - log(`sending response for statuses/update, uri=${uri}, body=${body}, response=${response.id}`) + log(`sending response for statuses/update, uri=${uri}, body=${body}, ` + + `response=${response.id}, headers=${JSON.stringify(this.req.headers)}`) return response; }) - // stream statuses/filter - .post((uri) => { + + nock('https://stream.twitter.com', { allowUnmocked: false }) + .persist() + .get((uri) => { const matched = uri.includes('statuses/filter') - if ( matched ) { - const q = url.parse(uri, true); - log(`getting request for POST uri=${uri}, ${JSON.stringify(q.query)}`); + if (matched) { + log(`getting request for GET uri=${uri}`); } return matched }) - .reply(200, function (uri, body) { - log(`sending response for statuses/filter, uri=${uri}, body=${body}`) - const stream = new Stream.Duplex() - stream.on("close", () => { - log(`should interception be over?`) - // nock.restore() - }) - return stream; + .reply(200, function (uri) { + const response = require(`./data/v_aminev/reply.json`) + return [ response ]; + }) + + nock('https://userstream.twitter.com', { allowUnmocked: false }) + .persist() + .get((uri) => { + log(`getting request for uri=${uri}`); + return true + }) + .reply(200, 'OK') + .post((uri) => { + log(`getting request for uri=${uri}`); + return true }) + .reply(200, 'OK') + + nock('https://sitestream.twitter.com', { allowUnmocked: false }) + .persist() + .get((uri) => { + log(`getting request for uri=${uri}`); + return true + }) + .reply(200, 'OK') + .post((uri) => { + log(`getting request for uri=${uri}`); + return true + }) + .reply(200, 'OK') + } module.exports = { diff --git a/test/suites/01.twitter.js b/test/suites/01.twitter.js index 831ad158..65fcfcb8 100644 --- a/test/suites/01.twitter.js +++ b/test/suites/01.twitter.js @@ -180,7 +180,7 @@ describe('twitter', function testSuite() { ); }); - it('should have collected some tweets', async () => { + it('should have collected some tweets (one account)', async () => { await Promise.delay(1500); const response = await request(uri.read, payload.read); @@ -197,7 +197,7 @@ describe('twitter', function testSuite() { })); }); - it('should have collected some tweets', async () => { + it('should have collected some tweets (multiple accounts)', async () => { await Promise.delay(1500); const response = await request(uri.read, payload.readMultiple); From 1b2c394df0a8fd18c1556d948cae62b7f9dc48a8 Mon Sep 17 00:00:00 2001 From: ildar Date: Fri, 26 May 2023 10:40:10 +0600 Subject: [PATCH 8/8] fix: minor changes --- test/suites/01.twitter.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/suites/01.twitter.js b/test/suites/01.twitter.js index 65fcfcb8..3b3799e8 100644 --- a/test/suites/01.twitter.js +++ b/test/suites/01.twitter.js @@ -124,13 +124,6 @@ describe('twitter', function testSuite() { after('cleanup feeds', () => service.knex('feeds').delete()); it('should return error if request to register is not valid', async () => { - // try { - // const response = service.amqp.publishAndWait(uri.register, payload.registerFail) - // console.log(response) - // } catch(err) { - // console.log(err) - // throw err - // } await assert.rejects(service.amqp.publishAndWait(uri.register, payload.registerFail), { name: 'HttpStatusError', statusCode: 400,